local_ctx.go 3.4 KB

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