kmodule.go 3.9 KB

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