local_ctx.go 3.6 KB

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