local_ctx.go 4.6 KB

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