dict_sub_hook.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // package dict_sub_hook -- словарь потребителей топика по подписке
  2. package dict_sub_hook
  3. import (
  4. "fmt"
  5. "sync"
  6. . "gitp78su.ipnodns.ru/svi/kern/v4/lev0/kalias"
  7. . "gitp78su.ipnodns.ru/svi/kern/v4/lev0/ktypes"
  8. . "gitp78su.ipnodns.ru/svi/kern/v4/lev1"
  9. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kctx"
  10. )
  11. // dictSubHook -- словарь потребителей топика по подписке
  12. type dictSubHook struct {
  13. ctx IKernelCtx
  14. dict map[AHandlerName]bool // В качестве ключа -- URL веб-хука
  15. block sync.RWMutex
  16. }
  17. // NewDictSubHook -- возвращает новый словарь веб-хуков одного топика
  18. func NewDictSubHook() IResult[IDictSubHook] {
  19. resKernCtx := kctx.GetKernelCtx()
  20. if resKernCtx.IsErr() {
  21. err := fmt.Errorf("dictSubHook.NewDictSubHook(): in get kernel ctx, err=\n\t%w", resKernCtx.Err())
  22. return NewErr[IDictSubHook](err)
  23. }
  24. sf := &dictSubHook{
  25. ctx: resKernCtx.Val(),
  26. dict: map[AHandlerName]bool{},
  27. }
  28. return NewRes(IDictSubHook(sf))
  29. }
  30. // Unsubscribe -- удаляет из словаря подписки обработчик
  31. func (sf *dictSubHook) Unsubscribe(handler IBusHandlerSubscribe) {
  32. sf.block.Lock()
  33. defer sf.block.Unlock()
  34. if handler == nil {
  35. sf.ctx.Log().Err("dictSubHook.Unsubscribe(): handler==nil")
  36. return
  37. }
  38. handlerName := handler.Name()
  39. delete(sf.dict, handlerName)
  40. sf.ctx.Del(string(handlerName))
  41. }
  42. // Subscribe -- добавляет в словарь подписки новый обработчик
  43. func (sf *dictSubHook) Subscribe(handler IBusHandlerSubscribe) IResult[bool] {
  44. sf.block.Lock()
  45. defer sf.block.Unlock()
  46. if handler == nil {
  47. err := fmt.Errorf("dictSubHook.Subscribe(): handler==nil")
  48. return NewErr[bool](err)
  49. }
  50. handlerName := handler.Name()
  51. sf.dict[handlerName] = true
  52. res := sf.ctx.Set(string(handlerName), handler, "subscribe handler")
  53. if res.IsErr() {
  54. err := fmt.Errorf("dictSubHook.Subscribe(): in set subscribe handler in kernel ctx, err=\n\t%w", res.Err())
  55. return NewErr[bool](err)
  56. }
  57. return NewRes(true)
  58. }
  59. // Read -- вызывает все обработчики словаря подписок
  60. func (sf *dictSubHook) Read(binMsg []byte) {
  61. sf.block.RLock()
  62. defer sf.block.RUnlock()
  63. for handlerName := range sf.dict {
  64. optHand := sf.ctx.Get(string(handlerName))
  65. if optHand.IsNone() {
  66. sf.ctx.Del(string(handlerName))
  67. continue
  68. }
  69. handler := optHand.Val().Val().(IBusHandlerSubscribe)
  70. go handler.FnBack(binMsg)
  71. }
  72. }