local_ctx.go 3.5 KB

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