local_ctx.go 4.4 KB

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