// package dict_sub_hook -- словарь потребителей топика по подписке. package dict_sub_hook import ( "fmt" "sync" mKa "gitp78su.ipnodns.ru/svi/kern/v4/lev0/kalias" mKt "gitp78su.ipnodns.ru/svi/kern/v4/lev0/ktypes" mL1 "gitp78su.ipnodns.ru/svi/kern/v4/lev1" "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kctx" ) // dictSubHook -- словарь потребителей топика по подписке. type dictSubHook struct { ctx mKt.IKernelCtx dict map[mKa.AHandlerName]bool // В качестве ключа -- URL веб-хука block sync.RWMutex } // NewDictSubHook -- возвращает новый словарь веб-хуков одного топика. func NewDictSubHook() mKt.IResult[mKt.IDictSubHook] { resKernCtx := kctx.GetKernelCtx() if resKernCtx.IsErr() { err := fmt.Errorf("dictSubHook.NewDictSubHook(): in get kernel ctx, err=\n\t%w", resKernCtx.Err()) return mL1.NewErr[mKt.IDictSubHook](err) } sf := &dictSubHook{ ctx: resKernCtx.Val(), dict: map[mKa.AHandlerName]bool{}, } return mL1.NewRes(mKt.IDictSubHook(sf)) } // Unsubscribe -- удаляет из словаря подписки обработчик. func (sf *dictSubHook) Unsubscribe(handler mKt.IBusHandlerSubscribe) { sf.block.Lock() defer sf.block.Unlock() if handler == nil { sf.ctx.Log().Err("dictSubHook.Unsubscribe(): handler==nil") return } handlerName := handler.Name() delete(sf.dict, handlerName) sf.ctx.Del(string(handlerName)) } // Subscribe -- добавляет в словарь подписки новый обработчик. func (sf *dictSubHook) Subscribe(handler mKt.IBusHandlerSubscribe) mKt.IResult[bool] { sf.block.Lock() defer sf.block.Unlock() if handler == nil { err := fmt.Errorf("dictSubHook.Subscribe(): handler==nil") return mL1.NewErr[bool](err) } handlerName := handler.Name() sf.dict[handlerName] = true res := sf.ctx.Set(string(handlerName), handler, "subscribe handler") if res.IsErr() { err := fmt.Errorf("dictSubHook.Subscribe(): in set subscribe handler in kernel ctx, err=\n\t%w", res.Err()) return mL1.NewErr[bool](err) } return mL1.NewRes(true) } // Read -- вызывает все обработчики словаря подписок. func (sf *dictSubHook) Read(binMsg []byte) { sf.block.RLock() defer sf.block.RUnlock() for handlerName := range sf.dict { optHand := sf.ctx.Get(string(handlerName)) if optHand.IsNone() { sf.ctx.Del(string(handlerName)) continue } handler := optHand.Val().Val().(mKt.IBusHandlerSubscribe) go handler.FnBack(binMsg) } }