// package kmodule -- модуль на основе ядра. package kmodule import ( "time" "gitp78su.ipnodns.ru/svi/kern/v4/d0" "gitp78su.ipnodns.ru/svi/kern/v4/d1" "gitp78su.ipnodns.ru/svi/kern/v4/d2/kern_ctx" "gitp78su.ipnodns.ru/svi/kern/v4/d2/kmodule/mod_stat" "gitp78su.ipnodns.ru/svi/kern/v4/d2/lti/bus_ent" "gitp78su.ipnodns.ru/svi/kern/v4/d2/lti/bus_ent/topic" "gitp78su.ipnodns.ru/svi/kern/v4/d2/lti/bus_spec" "gitp78su.ipnodns.ru/svi/kern/v4/d2/lti/kbus_local" "gitp78su.ipnodns.ru/svi/kern/v4/d3/mod_ent/module_name" "gitp78su.ipnodns.ru/svi/kern/v4/d3/mod_spec" ) // kModule -- модуль на основе ядра. type kModule struct { owner *d0.LOwner kCtx *kern_ctx.KernCtx lCtx *d1.LocalCtx name *module_name.LModuleName bus bus_spec.IKernelBus timePhase *d0.MSafeNum txtLive *d0.MTxt stat mod_spec.IModuleStat } // NewKernelModule -- возвращает новый модуль на основе ядра. func NewKernelModule(owner *d0.LOwner, name *module_name.LModuleName) mod_spec.IKernelModule { d0.If(name == nil).Hassert("NewKernelModule(): name==nil", []any{}) kCtx := kern_ctx.GetKernCtx() sf := &kModule{ owner: owner, kCtx: kCtx, lCtx: d1.NewLocalCtx(owner, kCtx.SelfCtx()), name: name, bus: kbus_local.GetKernelBusLocal(), timePhase: d0.MutSafeNum(owner, 1000), // 1000 msec txtLive: d0.MutTxt(""), stat: mod_stat.NewModStat(owner, name), } go sf.sigLive() return sf } // Owner -- возвращает владельца изолята func (sf *kModule) Owner() *d0.LOwner { return sf.owner } // Stat -- возвращает статистику модуля. func (sf *kModule) Stat() mod_spec.IModuleStat { return sf.stat } // Log -- возвращает буферный лог. func (sf *kModule) Log() *d1.LogBuf { return sf.lCtx.Log() } // Ctx -- возвращает контекст модуля. func (sf *kModule) Ctx() *d1.LocalCtx { return sf.lCtx } // Run -- запускает модуль в работу. func (sf *kModule) Run() { d0.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() d0.Bool { d0.If(true). Hassert("kModule.IsWork(): module='%v', parent not realized this method", []any{sf.name}) return false } // Live -- возвращает индикатор жизни модуля. func (sf *kModule) Live() *d0.LTxt { return sf.txtLive.Let() } var ( f0 = d0.Txt("|") f1 = d0.Txt("/") f2 = d0.Txt("-") f3 = d0.Txt("\\") ) // Сигнал жизни, каждые 5 сек публикует в шину метку. func (sf *kModule) sigLive() { var ( topic = topic.LetTopic(bus_ent.ATopic(sf.name.Get()) + "_live") iPhase = 0 res *d0.Result[d0.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() } } }