// package local_ctx -- локальный контекст. package local_ctx import ( "context" "gitp78su.ipnodns.ru/svi/kern/v4/d0" "gitp78su.ipnodns.ru/svi/kern/v4/d1/local_ctx/ctx_value" "gitp78su.ipnodns.ru/svi/kern/v4/d1/log_buf" "gitp78su.ipnodns.ru/svi/kern/v4/d1/lst_sort" ) // LocalCtx -- локальный контекст. type LocalCtx struct { *d0.MSafeMutex owner *d0.LOwner lCtx context.Context // Отменяемый контекст fnCancel func() // Функция отмены контекста dictVal map[d0.Txt]*ctx_value.CtxValue // Словарь различных значений lstSort *lst_sort.LstSort // Сортированный список значений log *log_buf.LogBuf // Локальный буфер } // NewLocalCtx -- возвращает новый локальный контекст. func NewLocalCtx(owner *d0.LOwner, ctx context.Context) *LocalCtx { d0.If(ctx == nil).Hassert("NewLocalCtx(): ctx==nil") d0.If(owner == nil).Hassert("NewLocalCtx(): LOwner==nil") lCtx, fnCancel := context.WithCancel(ctx) paramLogBuf := &log_buf.LogBufParam{ IsTerm_: d0.MutSafeBool(owner, true), Prefix_: d0.LetTxt("LocalCtx"), } sf := &LocalCtx{ owner: owner, MSafeMutex: d0.MutSafeMutex(), lCtx: lCtx, fnCancel: fnCancel, dictVal: map[d0.Txt]*ctx_value.CtxValue{}, lstSort: lst_sort.NewLstSort(), log: log_buf.NewLogBuf(paramLogBuf), } return sf } // Owner -- возвращает владельца контекста. func (sf *LocalCtx) Owner() *d0.LOwner { return sf.owner } // SelfCtx -- возвращает отменяемый контекст. func (sf *LocalCtx) SelfCtx() context.Context { return sf.lCtx } // Size -- возвращает размер контекста. func (sf *LocalCtx) Size() d0.Num { sf.RLock() defer sf.RUnlock() return d0.Num(len(sf.dictVal)) } // SortedList -- возвращает сортированный список значений. func (sf *LocalCtx) SortedList() []*ctx_value.CtxValue { return sf.lstSort.List() } // Log -- возвращает локальный буферный лог. func (sf *LocalCtx) Log() *log_buf.LogBuf { return sf.log } // Get -- возвращает хранимое значение. func (sf *LocalCtx) Get(key *d0.LTxt) *d0.Option[*ctx_value.CtxValue] { sf.RLock() defer sf.RUnlock() if key.Get() == "" { return d0.NewNone[*ctx_value.CtxValue]() } msg := d0.LetTxt("Get(): key='%v'", key).Get() sf.log.Debug(msg) val, isOk := sf.dictVal[key.Get()] if !isOk { return d0.NewNone[*ctx_value.CtxValue]() } return d0.NewSome(val) } // Del -- удаляет значение из контекста. func (sf *LocalCtx) Del(key *d0.LTxt) { sf.Lock() defer sf.Unlock() msg := d0.LetTxt("Del(): key='%v'", key).Get() sf.log.Debug(msg) val := sf.dictVal[key.Get()] delete(sf.dictVal, key.Get()) sf.lstSort.Del(val) } // Set -- добавляет значение в контекст. func (sf *LocalCtx) Set(key *d0.LTxt, val any, comment d0.Txt) { sf.Lock() defer sf.Unlock() msg := d0.LetTxt("Set(): key='%v'", key).Get() sf.log.Debug(msg) _val, isOk := sf.dictVal[key.Get()] if isOk { _val.Lock() _val.UpdateAt_ = d0.MutTimeAuto() _val.Val_ = val _val.Unlock() return } _val = ctx_value.NewCtxValue(key.Get(), val, comment) sf.dictVal[key.Get()] = _val sf.lstSort.Add(_val) } // Wait -- блокирующий вызов ожидания отмены контекста. func (sf *LocalCtx) Wait() { <-sf.lCtx.Done() } // Cancel -- отменяет контекст. func (sf *LocalCtx) Cancel() { sf.log.Warn("Cancel()") sf.fnCancel() } // Done -- готовность локального контекста func (sf *LocalCtx) Done() <-chan struct{} { return sf.lCtx.Done() }