local_ctx.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // package local_ctx -- локальный контекст.
  2. package local_ctx
  3. import (
  4. "context"
  5. "gitp78su.ipnodns.ru/svi/kern/v4/lev0"
  6. "gitp78su.ipnodns.ru/svi/kern/v4/lev1/comp_spec"
  7. "gitp78su.ipnodns.ru/svi/kern/v4/lev1/local_ctx/ctx_value"
  8. "gitp78su.ipnodns.ru/svi/kern/v4/lev1/log_buf"
  9. "gitp78su.ipnodns.ru/svi/kern/v4/lev1/lst_sort"
  10. )
  11. // LocalCtx -- локальный контекст.
  12. type LocalCtx struct {
  13. *lev0.MSafeMutex
  14. ctx context.Context // Отменяемый контекст
  15. fnCancel func() // Функция отмены контекста
  16. dictVal map[lev0.Txt]*ctx_value.CtxValue // Словарь различных значений
  17. lstSort *lst_sort.LstSort // Сортированный список значений
  18. log comp_spec.ILogBuf // Локальный буфер
  19. }
  20. // NewLocalCtx -- возвращает новый локальный контекст.
  21. func NewLocalCtx(ctx context.Context) *LocalCtx {
  22. lev0.If(ctx == nil).Hassert("NewLocalCtx(): ctx==nil")
  23. _ctx, fnCancel := context.WithCancel(ctx)
  24. paramLogBuf := &log_buf.LogBufParam{
  25. IsTerm_: lev0.MutSafeBool(true),
  26. Prefix_: lev0.LetTxt("LocalCtx"),
  27. }
  28. sf := &LocalCtx{
  29. MSafeMutex: lev0.MutSafeMutex(),
  30. ctx: _ctx,
  31. fnCancel: fnCancel,
  32. dictVal: map[lev0.Txt]*ctx_value.CtxValue{},
  33. lstSort: lst_sort.NewLstSort(),
  34. log: log_buf.NewLogBuf(paramLogBuf),
  35. }
  36. return sf
  37. }
  38. // Ctx -- возвращает отменяемый контекст.
  39. func (sf *LocalCtx) Ctx() context.Context {
  40. return sf.ctx
  41. }
  42. // Size -- возвращает размер контекста.
  43. func (sf *LocalCtx) Size() lev0.Num {
  44. sf.RLock()
  45. defer sf.RUnlock()
  46. return lev0.Num(len(sf.dictVal))
  47. }
  48. // SortedList -- возвращает сортированный список значений.
  49. func (sf *LocalCtx) SortedList() []*ctx_value.CtxValue {
  50. return sf.lstSort.List()
  51. }
  52. // Log -- возвращает локальный буферный лог.
  53. func (sf *LocalCtx) Log() comp_spec.ILogBuf {
  54. return sf.log
  55. }
  56. // Get -- возвращает хранимое значение.
  57. func (sf *LocalCtx) Get(key *lev0.LTxt) *lev0.Option[*ctx_value.CtxValue] {
  58. sf.RLock()
  59. defer sf.RUnlock()
  60. if key.Get() == "" {
  61. return lev0.NewNone[*ctx_value.CtxValue]()
  62. }
  63. msg := lev0.LetTxt("Get(): key='%v'", key).Get()
  64. sf.log.Debug(msg)
  65. val, isOk := sf.dictVal[key.Get()]
  66. if !isOk {
  67. return lev0.NewNone[*ctx_value.CtxValue]()
  68. }
  69. return lev0.NewSome(val)
  70. }
  71. // Del -- удаляет значение из контекста.
  72. func (sf *LocalCtx) Del(key *lev0.LTxt) {
  73. sf.Lock()
  74. defer sf.Unlock()
  75. msg := lev0.LetTxt("Del(): key='%v'", key).Get()
  76. sf.log.Debug(msg)
  77. val := sf.dictVal[key.Get()]
  78. delete(sf.dictVal, key.Get())
  79. sf.lstSort.Del(val)
  80. }
  81. // Set -- добавляет значение в контекст.
  82. func (sf *LocalCtx) Set(key *lev0.LTxt, val any, comment lev0.Txt) {
  83. sf.Lock()
  84. defer sf.Unlock()
  85. msg := lev0.LetTxt("Set(): key='%v'", key).Get()
  86. sf.log.Debug(msg)
  87. _val, isOk := sf.dictVal[key.Get()]
  88. if isOk {
  89. _val.Lock()
  90. _val.UpdateAt_ = lev0.MutTimeAuto()
  91. _val.Val_ = val
  92. _val.Unlock()
  93. return
  94. }
  95. _val = ctx_value.NewCtxValue(key.Get(), val, comment)
  96. sf.dictVal[key.Get()] = _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. }