local_ctx.go 4.5 KB

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