local_ctx.go 3.2 KB

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