kmodule.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // package kmodule -- модуль на основе ядра.
  2. package kmodule
  3. import (
  4. "fmt"
  5. "time"
  6. mL0 "gitp78su.ipnodns.ru/svi/kern/v4/lev0"
  7. "gitp78su.ipnodns.ru/svi/kern/v4/lev0/alias"
  8. mKa "gitp78su.ipnodns.ru/svi/kern/v4/lev0/alias"
  9. mKh "gitp78su.ipnodns.ru/svi/kern/v4/lev0/helpers"
  10. mKt "gitp78su.ipnodns.ru/svi/kern/v4/lev0/ktypes"
  11. mL1 "gitp78su.ipnodns.ru/svi/kern/v4/lev1"
  12. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kbus_local"
  13. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kctx"
  14. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kmodule/mod_stat"
  15. )
  16. // kModule -- модуль на основе ядра.
  17. type kModule struct {
  18. kCtx mKt.IKernelCtx
  19. ctx mKt.ILocalCtx
  20. name *mKa.AModuleName
  21. bus mKt.IKernelBus
  22. timePhase mKt.ISafeInt
  23. strLive mKt.ISafeString
  24. stat mKt.IModuleStat
  25. }
  26. // NewKernelModule -- возвращает новый модуль на основе ядра.
  27. func NewKernelModule(name *mKa.AModuleName) *mL0.Result[mKt.IKernelModule] {
  28. mL0.Hassert(name != nil, "NewKernelModule(): name==nil")
  29. resCtx := kctx.GetKernelCtx()
  30. if resCtx.IsErr() {
  31. err := fmt.Errorf("NewKernelModule(): in get kernel ctx,err=%v", resCtx.Err())
  32. return mL0.NewErr[mKt.IKernelModule](err)
  33. }
  34. kCtx := resCtx.Val()
  35. resLocal := kbus_local.GetKernelBusLocal()
  36. if resLocal.IsErr() {
  37. err := fmt.Errorf("NewKernelModule(): in get kernel bus local,err=%v", resLocal.Err())
  38. return mL0.NewErr[mKt.IKernelModule](err)
  39. }
  40. resLocCtx := mL1.NewLocalCtx(kCtx.Ctx())
  41. if resLocCtx.IsErr() {
  42. err := fmt.Errorf("NewKernelModule(): in new local ctx,err=%v", resLocCtx.Err())
  43. return mL0.NewErr[mKt.IKernelModule](err)
  44. }
  45. sf := &kModule{
  46. kCtx: kCtx,
  47. ctx: resLocCtx.Val(),
  48. name: name,
  49. bus: resLocal.Val(),
  50. timePhase: mL1.NewSafeInt(1000), // 1000 msec
  51. strLive: mL1.NewSafeString(),
  52. stat: mod_stat.NewModStat(name),
  53. }
  54. go sf.sigLive()
  55. return mL0.NewRes(mKt.IKernelModule(sf))
  56. }
  57. // Stat -- возвращает статистику модуля.
  58. func (sf *kModule) Stat() mKt.IModuleStat {
  59. return sf.stat
  60. }
  61. // Log -- возвращает буферный лог.
  62. func (sf *kModule) Log() mKt.ILogBuf {
  63. return sf.ctx.Log()
  64. }
  65. // Ctx -- возвращает контекст модуля.
  66. func (sf *kModule) Ctx() mKt.ILocalCtx {
  67. return sf.ctx
  68. }
  69. // Run -- запускает модуль в работу.
  70. func (sf *kModule) Run() {
  71. mKh.Hassert(false, "kModule.Run(): module='%v', parent not realized this method", sf.name)
  72. }
  73. // Name -- возвращает уникальное имя модуля.
  74. func (sf *kModule) Name() *mKa.AModuleName {
  75. return sf.name
  76. }
  77. // IsWork -- возвращает признак состояния работы.
  78. func (sf *kModule) IsWork() bool {
  79. mKh.Hassert(false, "kModule.IsWork(): module='%v', parent not realized this method", sf.name)
  80. return false
  81. }
  82. // Live -- возвращает индикатор жизни модуля.
  83. func (sf *kModule) Live() string {
  84. return sf.strLive.Get()
  85. }
  86. // Сигнал жизни, каждые 5 сек публикует в шину метку.
  87. func (sf *kModule) sigLive() {
  88. var (
  89. topic = alias.NewATopic(sf.name.Get() + "_live")
  90. iPhase = 0
  91. res *mL0.Result[bool]
  92. )
  93. fnPhase := func() {
  94. time.Sleep(time.Millisecond * time.Duration(sf.timePhase.Get()))
  95. select {
  96. case <-sf.kCtx.Ctx().Done():
  97. return
  98. default:
  99. switch iPhase {
  100. case 0:
  101. sf.strLive.Set("|")
  102. res = sf.bus.Publish(topic, sf.strLive.Byte())
  103. case 1:
  104. sf.strLive.Set("/")
  105. res = sf.bus.Publish(topic, sf.strLive.Byte())
  106. case 2:
  107. sf.strLive.Set("-")
  108. res = sf.bus.Publish(topic, sf.strLive.Byte())
  109. case 3:
  110. sf.strLive.Set("\\")
  111. res = sf.bus.Publish(topic, sf.strLive.Byte())
  112. iPhase = -1
  113. }
  114. res.Hassert("kModule.sigLive(): name=%v, in publish live", sf.Name())
  115. iPhase++
  116. sf.stat.Add(1)
  117. }
  118. }
  119. for {
  120. select {
  121. case <-sf.kCtx.Ctx().Done():
  122. return
  123. default:
  124. fnPhase()
  125. }
  126. }
  127. }