| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- // 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()
- }
- }
- }
|