// package kmodule -- модуль на основе ядра. package kmodule import ( "fmt" "time" mL0 "gitp78su.ipnodns.ru/svi/kern/v4/lev0" "gitp78su.ipnodns.ru/svi/kern/v4/lev0/alias" mKa "gitp78su.ipnodns.ru/svi/kern/v4/lev0/alias" mKh "gitp78su.ipnodns.ru/svi/kern/v4/lev0/helpers" mKt "gitp78su.ipnodns.ru/svi/kern/v4/lev0/ktypes" mL1 "gitp78su.ipnodns.ru/svi/kern/v4/lev1" "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 mKt.IKernelCtx ctx mKt.ILocalCtx name *mKa.AModuleName bus mKt.IKernelBus timePhase mKt.ISafeInt strLive mKt.ISafeString stat mKt.IModuleStat } // NewKernelModule -- возвращает новый модуль на основе ядра. func NewKernelModule(name *mKa.AModuleName) *mL0.Result[mKt.IKernelModule] { mL0.Hassert(name != nil, "NewKernelModule(): name==nil") resCtx := kctx.GetKernelCtx() if resCtx.IsErr() { err := fmt.Errorf("NewKernelModule(): in get kernel ctx,err=%v", resCtx.Err()) return mL0.NewErr[mKt.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 mL0.NewErr[mKt.IKernelModule](err) } resLocCtx := mL1.NewLocalCtx(kCtx.Ctx()) if resLocCtx.IsErr() { err := fmt.Errorf("NewKernelModule(): in new local ctx,err=%v", resLocCtx.Err()) return mL0.NewErr[mKt.IKernelModule](err) } sf := &kModule{ kCtx: kCtx, ctx: resLocCtx.Val(), name: name, bus: resLocal.Val(), timePhase: mL1.NewSafeInt(1000), // 1000 msec strLive: mL1.NewSafeString(), stat: mod_stat.NewModStat(name), } go sf.sigLive() return mL0.NewRes(mKt.IKernelModule(sf)) } // Stat -- возвращает статистику модуля. func (sf *kModule) Stat() mKt.IModuleStat { return sf.stat } // Log -- возвращает буферный лог. func (sf *kModule) Log() mKt.ILogBuf { return sf.ctx.Log() } // Ctx -- возвращает контекст модуля. func (sf *kModule) Ctx() mKt.ILocalCtx { return sf.ctx } // Run -- запускает модуль в работу. func (sf *kModule) Run() { mKh.Hassert(false, "kModule.Run(): module='%v', parent not realized this method", sf.name) } // Name -- возвращает уникальное имя модуля. func (sf *kModule) Name() *mKa.AModuleName { return sf.name } // IsWork -- возвращает признак состояния работы. func (sf *kModule) IsWork() bool { mKh.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 = alias.NewATopic(sf.name.Get() + "_live") iPhase = 0 res *mL0.Result[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(topic, sf.strLive.Byte()) case 1: sf.strLive.Set("/") res = sf.bus.Publish(topic, sf.strLive.Byte()) case 2: sf.strLive.Set("-") res = sf.bus.Publish(topic, sf.strLive.Byte()) case 3: sf.strLive.Set("\\") res = sf.bus.Publish(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() } } }