kmodule.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // package kmodule -- модуль на основе ядра.
  2. package kmodule
  3. import (
  4. "time"
  5. "gitp78su.ipnodns.ru/svi/kern/v4/d0"
  6. "gitp78su.ipnodns.ru/svi/kern/v4/d1"
  7. "gitp78su.ipnodns.ru/svi/kern/v4/d2/kern_ctx"
  8. "gitp78su.ipnodns.ru/svi/kern/v4/d2/kmodule/mod_stat"
  9. "gitp78su.ipnodns.ru/svi/kern/v4/d2/lti/bus_ent"
  10. "gitp78su.ipnodns.ru/svi/kern/v4/d2/lti/bus_ent/topic"
  11. "gitp78su.ipnodns.ru/svi/kern/v4/d2/lti/bus_spec"
  12. "gitp78su.ipnodns.ru/svi/kern/v4/d2/lti/kbus_local"
  13. "gitp78su.ipnodns.ru/svi/kern/v4/d3/mod_ent/module_name"
  14. "gitp78su.ipnodns.ru/svi/kern/v4/d3/mod_spec"
  15. )
  16. // kModule -- модуль на основе ядра.
  17. type kModule struct {
  18. owner *d0.LOwner
  19. kCtx *kern_ctx.KernCtx
  20. lCtx *d1.LocalCtx
  21. name *module_name.LModuleName
  22. bus bus_spec.IKernelBus
  23. timePhase *d0.MSafeNum
  24. txtLive *d0.MTxt
  25. stat mod_spec.IModuleStat
  26. }
  27. // NewKernelModule -- возвращает новый модуль на основе ядра.
  28. func NewKernelModule(owner *d0.LOwner, name *module_name.LModuleName) mod_spec.IKernelModule {
  29. d0.If(name == nil).Hassert("NewKernelModule(): name==nil", []any{})
  30. kCtx := kern_ctx.GetKernCtx()
  31. sf := &kModule{
  32. owner: owner,
  33. kCtx: kCtx,
  34. lCtx: d1.NewLocalCtx(owner, kCtx.SelfCtx()),
  35. name: name,
  36. bus: kbus_local.GetKernelBusLocal(),
  37. timePhase: d0.MutSafeNum(owner, 1000), // 1000 msec
  38. txtLive: d0.MutTxt(""),
  39. stat: mod_stat.NewModStat(owner, name),
  40. }
  41. go sf.sigLive()
  42. return sf
  43. }
  44. // Owner -- возвращает владельца изолята
  45. func (sf *kModule) Owner() *d0.LOwner {
  46. return sf.owner
  47. }
  48. // Stat -- возвращает статистику модуля.
  49. func (sf *kModule) Stat() mod_spec.IModuleStat {
  50. return sf.stat
  51. }
  52. // Log -- возвращает буферный лог.
  53. func (sf *kModule) Log() *d1.LogBuf {
  54. return sf.lCtx.Log()
  55. }
  56. // Ctx -- возвращает контекст модуля.
  57. func (sf *kModule) Ctx() *d1.LocalCtx {
  58. return sf.lCtx
  59. }
  60. // Run -- запускает модуль в работу.
  61. func (sf *kModule) Run() {
  62. d0.If(true).
  63. Hassert("kModule.Run(): module='%v', parent not realized this method",
  64. []any{sf.name})
  65. }
  66. // Name -- возвращает уникальное имя модуля.
  67. func (sf *kModule) Name() *module_name.LModuleName {
  68. return sf.name
  69. }
  70. // IsWork -- возвращает признак состояния работы.
  71. func (sf *kModule) IsWork() d0.Bool {
  72. d0.If(true).
  73. Hassert("kModule.IsWork(): module='%v', parent not realized this method",
  74. []any{sf.name})
  75. return false
  76. }
  77. // Live -- возвращает индикатор жизни модуля.
  78. func (sf *kModule) Live() *d0.LTxt {
  79. return sf.txtLive.Let()
  80. }
  81. var (
  82. f0 = d0.Txt("|")
  83. f1 = d0.Txt("/")
  84. f2 = d0.Txt("-")
  85. f3 = d0.Txt("\\")
  86. )
  87. // Сигнал жизни, каждые 5 сек публикует в шину метку.
  88. func (sf *kModule) sigLive() {
  89. var (
  90. topic = topic.LetTopic(bus_ent.ATopic(sf.name.Get()) + "_live")
  91. iPhase = 0
  92. res *d0.Result[d0.Bool]
  93. )
  94. fnPhase := func() {
  95. time.Sleep(time.Millisecond * time.Duration(sf.timePhase.Get()))
  96. select {
  97. case <-sf.kCtx.Done():
  98. return
  99. default:
  100. switch iPhase {
  101. case 0:
  102. sf.txtLive.Set(f0)
  103. res = sf.bus.Publish(topic, sf.txtLive.Byte())
  104. case 1:
  105. sf.txtLive.Set(f1)
  106. res = sf.bus.Publish(topic, sf.txtLive.Byte())
  107. case 2:
  108. sf.txtLive.Set(f2)
  109. res = sf.bus.Publish(topic, sf.txtLive.Byte())
  110. case 3:
  111. sf.txtLive.Set(f3)
  112. res = sf.bus.Publish(topic, sf.txtLive.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.SelfCtx().Done():
  123. return
  124. default:
  125. fnPhase()
  126. }
  127. }
  128. }