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