// package kmodule -- модуль на основе ядра package kmodule import ( "fmt" "time" . "gitp78su.ipnodns.ru/svi/kern/v4/lev0/helpers" . "gitp78su.ipnodns.ru/svi/kern/v4/lev0/kalias" . "gitp78su.ipnodns.ru/svi/kern/v4/lev0/ktypes" "gitp78su.ipnodns.ru/svi/kern/v4/lev1/local_ctx" . "gitp78su.ipnodns.ru/svi/kern/v4/lev1/result" "gitp78su.ipnodns.ru/svi/kern/v4/lev1/safe_int" "gitp78su.ipnodns.ru/svi/kern/v4/lev1/safe_string" "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kbus_local" "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kctx" "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kmodule/mod_stat" ) // kModule -- модуль на основе ядра type kModule struct { kCtx IKernelCtx ctx ILocalCtx name AModuleName bus IKernelBus timePhase ISafeInt strLive ISafeString stat IModuleStat } // NewKernelModule -- возвращает новый модуль на основе ядра func NewKernelModule(name AModuleName) IResult[IKernelModule] { if name == "" { err := fmt.Errorf("NewKernelModule(): name is empty") return NewErr[IKernelModule](err) } resCtx := kctx.GetKernelCtx() if resCtx.IsErr() { err := fmt.Errorf("NewKernelModule(): in get kernel ctx,err=%v", resCtx.Err()) return NewErr[IKernelModule](err) } kCtx := resCtx.Val() resLocal := kbus_local.GetKernelBusLocal() if resLocal.IsErr() { err := fmt.Errorf("NewKernelModule(): in get kernel bus local,err=%v", resLocal.Err()) return NewErr[IKernelModule](err) } resLocCtx := local_ctx.NewLocalCtx(kCtx.Ctx()) if resLocCtx.IsErr() { err := fmt.Errorf("NewKernelModule(): in new local ctx,err=%v", resLocCtx.Err()) return NewErr[IKernelModule](err) } sf := &kModule{ kCtx: kCtx, ctx: resLocCtx.Val(), name: name, bus: resLocal.Val(), timePhase: safe_int.NewSafeInt(1000), // 1000 msec strLive: safe_string.NewSafeString(), stat: mod_stat.NewModStat(name), } go sf.sigLive() return NewRes(IKernelModule(sf)) } // Stat -- возвращает статистику модуля func (sf *kModule) Stat() IModuleStat { return sf.stat } // Log -- возвращает буферный лог func (sf *kModule) Log() ILogBuf { return sf.ctx.Log() } // Ctx -- возвращает контекст модуля func (sf *kModule) Ctx() ILocalCtx { return sf.ctx } // Run -- запускает модуль в работу func (sf *kModule) Run() { Hassert(false, "kModule.Run(): module='%v', parent not realized this method", sf.name) } // Name -- возвращает уникальное имя модуля func (sf *kModule) Name() AModuleName { return sf.name } // IsWork -- возвращает признак состояния работы func (sf *kModule) IsWork() bool { Hassert(false, "kModule.IsWork(): module='%v', parent not realized this method", sf.name) return false } // Live -- возвращает индикатор жизни модуля func (sf *kModule) Live() string { return sf.strLive.Get() } // Сигнал жизни, каждые 5 сек публикует в шину метку func (sf *kModule) sigLive() { var ( topic = sf.name + "_live" iPhase = 0 res IResult[bool] ) fnPhase := func() { time.Sleep(time.Millisecond * time.Duration(sf.timePhase.Get())) select { case <-sf.kCtx.Ctx().Done(): return default: switch iPhase { case 0: sf.strLive.Set("|") res = sf.bus.Publish(ATopic(topic), sf.strLive.Byte()) case 1: sf.strLive.Set("/") res = sf.bus.Publish(ATopic(topic), sf.strLive.Byte()) case 2: sf.strLive.Set("-") res = sf.bus.Publish(ATopic(topic), sf.strLive.Byte()) case 3: sf.strLive.Set("\\") res = sf.bus.Publish(ATopic(topic), sf.strLive.Byte()) iPhase = -1 } res.Hassert("kModule.sigLive(): name=%v, in publish live", sf.Name()) iPhase++ sf.stat.Add(1) } } for { select { case <-sf.kCtx.Ctx().Done(): return default: fnPhase() } } }