local_ctx.go 3.3 KB

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