local_ctx.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // package local_ctx -- локальный контекст
  2. package local_ctx
  3. import (
  4. "context"
  5. "fmt"
  6. "sync"
  7. "gitp78su.ipnodns.ru/svi/kern/v4/lev0/helpers"
  8. . "gitp78su.ipnodns.ru/svi/kern/v4/lev0/ktypes"
  9. "gitp78su.ipnodns.ru/svi/kern/v4/lev1/ctx_value"
  10. "gitp78su.ipnodns.ru/svi/kern/v4/lev1/log_buf"
  11. "gitp78su.ipnodns.ru/svi/kern/v4/lev1/lst_sort"
  12. . "gitp78su.ipnodns.ru/svi/kern/v4/lev1/option"
  13. . "gitp78su.ipnodns.ru/svi/kern/v4/lev1/result"
  14. )
  15. // LocalCtx -- локальный контекст
  16. type LocalCtx struct {
  17. sync.RWMutex
  18. ctx context.Context // Отменяемый контекст
  19. fnCancel func() // Функция отмены контекста
  20. dictVal map[string]ICtxValue // Словарь различных значений
  21. lstSort *lst_sort.LstSort // Сортированный список значений
  22. log ILogBuf // Локальный буфер
  23. }
  24. // NewLocalCtx -- возвращает новый локальный контекст
  25. func NewLocalCtx(ctx context.Context) IResult[*LocalCtx] {
  26. if ctx == nil {
  27. err := fmt.Errorf("NewLocalCtx(): ctx==nil")
  28. return NewErr[*LocalCtx](err)
  29. }
  30. _ctx, fnCancel := context.WithCancel(ctx)
  31. sf := &LocalCtx{
  32. ctx: _ctx,
  33. fnCancel: fnCancel,
  34. dictVal: map[string]ICtxValue{},
  35. lstSort: lst_sort.NewLstSort(),
  36. log: log_buf.NewLogBuf(log_buf.OptIsTerm(true), log_buf.OptPrefix("LocalCtx")),
  37. }
  38. _ = ILocalCtx(sf)
  39. return NewRes(sf)
  40. }
  41. // Ctx -- возвращает отменяемый контекст
  42. func (sf *LocalCtx) Ctx() context.Context {
  43. return sf.ctx
  44. }
  45. // Size -- возвращает размер контекста
  46. func (sf *LocalCtx) Size() int {
  47. sf.RLock()
  48. defer sf.RUnlock()
  49. return len(sf.dictVal)
  50. }
  51. // SortedList -- возвращает сортированный список значений
  52. func (sf *LocalCtx) SortedList() []ICtxValue {
  53. return sf.lstSort.List()
  54. }
  55. // Log -- возвращает локальный буферный лог
  56. func (sf *LocalCtx) Log() ILogBuf {
  57. return sf.log
  58. }
  59. // Get -- возвращает хранимое значение
  60. func (sf *LocalCtx) Get(key string) IOption[ICtxValue] {
  61. sf.RLock()
  62. defer sf.RUnlock()
  63. if key == "" {
  64. return NewNone[ICtxValue]()
  65. }
  66. sf.log.Debug("Get(): key='%v'", key)
  67. val, isOk := sf.dictVal[key]
  68. if !isOk {
  69. return NewNone[ICtxValue]()
  70. }
  71. return NewOpt(val)
  72. }
  73. // Del -- удаляет значение из контекста
  74. func (sf *LocalCtx) Del(key string) {
  75. sf.Lock()
  76. defer sf.Unlock()
  77. sf.log.Debug("Del(): key='%v'", key)
  78. val := sf.dictVal[key]
  79. delete(sf.dictVal, key)
  80. sf.lstSort.Del(val)
  81. }
  82. // Set -- добавляет значение в контекст
  83. func (sf *LocalCtx) Set(key string, val any, comment string) IResult[bool] {
  84. sf.Lock()
  85. defer sf.Unlock()
  86. sf.log.Debug("Set(): key='%v'", key)
  87. _val, isOk := sf.dictVal[key]
  88. if isOk {
  89. val0 := _val.(*ctx_value.CtxValue)
  90. val0.Lock()
  91. val0.UpdateAt_ = helpers.TimeNowStr()
  92. val0.Val_ = val
  93. val0.Unlock()
  94. return NewRes(true)
  95. }
  96. resVal := ctx_value.NewCtxValue(key, val, comment)
  97. if resVal.IsErr() {
  98. return NewErr[bool](resVal.Err())
  99. }
  100. _val = resVal.Val()
  101. sf.dictVal[key] = _val
  102. sf.lstSort.Add(_val)
  103. return NewRes(true)
  104. }
  105. // Wait -- блокирующий вызов ожидания отмены контекста
  106. func (sf *LocalCtx) Wait() {
  107. <-sf.ctx.Done()
  108. }
  109. // Cancel -- отменяет контекст
  110. func (sf *LocalCtx) Cancel() {
  111. sf.log.Warn("Cancel()")
  112. sf.fnCancel()
  113. }