local_ctx.go 4.6 KB

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