local_ctx.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // package local_ctx -- локальный контекст
  2. package local_ctx
  3. import (
  4. "context"
  5. "fmt"
  6. "sync"
  7. "gitp78su.ipnodns.ru/svi/kern/v4/kc/log_buf"
  8. . "gitp78su.ipnodns.ru/svi/kern/v4/lev0/ktypes"
  9. "gitp78su.ipnodns.ru/svi/kern/v4/lev1/ctx_value"
  10. . "gitp78su.ipnodns.ru/svi/kern/v4/lev1/helpers"
  11. "gitp78su.ipnodns.ru/svi/kern/v4/lev1/lst_sort"
  12. . "gitp78su.ipnodns.ru/svi/kern/v4/lev1/result"
  13. )
  14. // LocalCtx -- локальный контекст
  15. type LocalCtx struct {
  16. sync.RWMutex
  17. ctx context.Context // Отменяемый контекст
  18. fnCancel func() // Функция отмены контекста
  19. dictVal map[string]ICtxValue // Словарь различных значений
  20. lstSort *lst_sort.LstSort // Сортированный список значений
  21. log ILogBuf // Локальный буфер
  22. }
  23. // NewLocalCtx -- возвращает новый локальный контекст
  24. func NewLocalCtx(ctx context.Context) ILocalCtx {
  25. Hassert(ctx != nil, "NewLocalCtx(): ctx==nil")
  26. _ctx, fnCancel := context.WithCancel(ctx)
  27. sf := &LocalCtx{
  28. ctx: _ctx,
  29. fnCancel: fnCancel,
  30. dictVal: map[string]ICtxValue{},
  31. lstSort: lst_sort.NewLstSort(),
  32. log: log_buf.NewLogBuf(log_buf.OptIsTerm(true), log_buf.OptPrefix("LocalCtx")),
  33. }
  34. return sf
  35. }
  36. // Ctx -- возвращает отменяемый контекст
  37. func (sf *LocalCtx) Ctx() context.Context {
  38. return sf.ctx
  39. }
  40. // Size -- возвращает размер контекста
  41. func (sf *LocalCtx) Size() int {
  42. sf.RLock()
  43. defer sf.RUnlock()
  44. return len(sf.dictVal)
  45. }
  46. // SortedList -- возвращает сортированный список значений
  47. func (sf *LocalCtx) SortedList() []ICtxValue {
  48. return sf.lstSort.List()
  49. }
  50. // Log -- возвращает локальный буферный лог
  51. func (sf *LocalCtx) Log() ILogBuf {
  52. return sf.log
  53. }
  54. // Get -- возвращает хранимое значение
  55. func (sf *LocalCtx) Get(key string) IResult[ICtxValue] {
  56. sf.RLock()
  57. defer sf.RUnlock()
  58. Hassert(key != "", "localCtx.Get(): key is empty")
  59. sf.log.Debug("Get(): key='%v'", key)
  60. val, isOk := sf.dictVal[key]
  61. if !isOk {
  62. err := fmt.Errorf("LocalCtx.Get(): key='%v' not found", key)
  63. return NewErr[ICtxValue](err)
  64. }
  65. return NewRes(val)
  66. }
  67. // Del -- удаляет значение из контекста
  68. func (sf *LocalCtx) Del(key string) {
  69. sf.Lock()
  70. defer sf.Unlock()
  71. sf.log.Debug("Del(): key='%v'", key)
  72. val := sf.dictVal[key]
  73. delete(sf.dictVal, key)
  74. sf.lstSort.Del(val)
  75. }
  76. // Set -- добавляет значение в контекст
  77. func (sf *LocalCtx) Set(key string, val any, comment string) IResult[bool] {
  78. sf.Lock()
  79. defer sf.Unlock()
  80. sf.log.Debug("Set(): key='%v'", key)
  81. _val, isOk := sf.dictVal[key]
  82. if isOk {
  83. val0 := _val.(*ctx_value.CtxValue)
  84. val0.Lock()
  85. val0.UpdateAt_ = TimeNowStr()
  86. val0.Val_ = val
  87. val0.Unlock()
  88. return NewRes(true)
  89. }
  90. _val = ctx_value.NewCtxValue(key, val, comment)
  91. sf.dictVal[key] = _val
  92. sf.lstSort.Add(_val)
  93. return NewRes(true)
  94. }
  95. // Done -- блокирующий вызов ожидания отмены контекста
  96. func (sf *LocalCtx) Done() {
  97. <-sf.ctx.Done()
  98. }
  99. // Cancel -- отменяет контекст
  100. func (sf *LocalCtx) Cancel() {
  101. sf.log.Warn("Cancel()")
  102. sf.fnCancel()
  103. }