kmodule.go 3.9 KB

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