// package kmodule -- модуль на основе ядра. package kmodule import ( "time" "gitp78su.ipnodns.ru/svi/kern/v4/lev0" "gitp78su.ipnodns.ru/svi/kern/v4/lev1" "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kern_ctx" "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kmodule/mod_stat" "gitp78su.ipnodns.ru/svi/kern/v4/lev2/lti/bus_ent" "gitp78su.ipnodns.ru/svi/kern/v4/lev2/lti/bus_ent/topic" "gitp78su.ipnodns.ru/svi/kern/v4/lev2/lti/bus_spec" "gitp78su.ipnodns.ru/svi/kern/v4/lev2/lti/kbus_local" "gitp78su.ipnodns.ru/svi/kern/v4/lev3/mod_ent/module_name" "gitp78su.ipnodns.ru/svi/kern/v4/lev3/mod_spec" ) // kModule -- модуль на основе ядра. type kModule struct { kCtx *kern_ctx.KernCtx lCtx *lev1.LocalCtx name *module_name.LModuleName bus bus_spec.IKernelBus timePhase *lev0.MSafeNum txtLive *lev0.MTxt stat mod_spec.IModuleStat } // NewKernelModule -- возвращает новый модуль на основе ядра. func NewKernelModule(name *module_name.LModuleName) mod_spec.IKernelModule { lev0.If(name == nil).Hassert("NewKernelModule(): name==nil", []any{}) kCtx := kern_ctx.GetKernCtx() sf := &kModule{ kCtx: kCtx, lCtx: lev1.NewLocalCtx(kCtx.SelfCtx()), name: name, bus: kbus_local.GetKernelBusLocal(), timePhase: lev0.MutSafeNum(1000), // 1000 msec txtLive: lev0.MutTxt(""), stat: mod_stat.NewModStat(name), } go sf.sigLive() return sf } // Stat -- возвращает статистику модуля. func (sf *kModule) Stat() mod_spec.IModuleStat { return sf.stat } // Log -- возвращает буферный лог. func (sf *kModule) Log() *lev1.LogBuf { return sf.lCtx.Log() } // Ctx -- возвращает контекст модуля. func (sf *kModule) Ctx() *lev1.LocalCtx { return sf.lCtx } // Run -- запускает модуль в работу. func (sf *kModule) Run() { lev0.If(true). Hassert("kModule.Run(): module='%v', parent not realized this method", []any{sf.name}) } // Name -- возвращает уникальное имя модуля. func (sf *kModule) Name() *module_name.LModuleName { return sf.name } // IsWork -- возвращает признак состояния работы. func (sf *kModule) IsWork() lev0.Bool { lev0.If(true). Hassert("kModule.IsWork(): module='%v', parent not realized this method", []any{sf.name}) return false } // Live -- возвращает индикатор жизни модуля. func (sf *kModule) Live() *lev0.LTxt { return sf.txtLive.Let() } var ( f0 = lev0.Txt("|") f1 = lev0.Txt("/") f2 = lev0.Txt("-") f3 = lev0.Txt("\\") ) // Сигнал жизни, каждые 5 сек публикует в шину метку. func (sf *kModule) sigLive() { var ( topic = topic.LetTopic(bus_ent.ATopic(sf.name.Get()) + "_live") iPhase = 0 res *lev0.Result[lev0.Bool] ) fnPhase := func() { time.Sleep(time.Millisecond * time.Duration(sf.timePhase.Get())) select { case <-sf.kCtx.Done(): return default: switch iPhase { case 0: sf.txtLive.Set(f0) res = sf.bus.Publish(topic, sf.txtLive.Byte()) case 1: sf.txtLive.Set(f1) res = sf.bus.Publish(topic, sf.txtLive.Byte()) case 2: sf.txtLive.Set(f2) res = sf.bus.Publish(topic, sf.txtLive.Byte()) case 3: sf.txtLive.Set(f3) res = sf.bus.Publish(topic, sf.txtLive.Byte()) iPhase = -1 } res.Hassert("kModule.sigLive(): name=%v, in publish live", sf.Name()) iPhase++ sf.stat.Add(1) } } for { select { case <-sf.kCtx.SelfCtx().Done(): return default: fnPhase() } } }