kmonolit.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // package kmonolit -- модульный монолит на основе ядра.
  2. package kmonolit
  3. import (
  4. "gitp78su.ipnodns.ru/svi/kern/v4/d0"
  5. "gitp78su.ipnodns.ru/svi/kern/v4/d1"
  6. "gitp78su.ipnodns.ru/svi/kern/v4/d2"
  7. "gitp78su.ipnodns.ru/svi/kern/v4/d3/mod_ent"
  8. "gitp78su.ipnodns.ru/svi/kern/v4/d3/mod_spec"
  9. )
  10. // LModMonolit -- объект модульного монолита.
  11. type LModMonolit struct {
  12. owner *d0.LOwner
  13. kCtx *d2.KernCtx
  14. lCtx *d1.LocalCtx
  15. log *d1.LogBuf
  16. name mod_ent.AModuleName
  17. isLocal *d0.LBool
  18. isWork *d0.MSafeBool
  19. isEnd *d0.MSafeBool
  20. dict map[mod_ent.AModuleName]mod_spec.IKernelModule // Словарь модулей монолита
  21. }
  22. var (
  23. mon *LModMonolit
  24. block = d0.MutSafeMutex()
  25. )
  26. var (
  27. owner = d0.LetOwner(0, "owner_test")
  28. txtIsLocal = d0.LetTxt(owner, "isLocal")
  29. )
  30. // LetModMonolit -- возвращает синглтон модуля-монолита.
  31. func LetModMonolit(name mod_ent.AModuleName) *LModMonolit {
  32. block.Lock()
  33. defer block.Unlock()
  34. if mon != nil {
  35. return mon
  36. }
  37. owner := d0.LetOwner(1, "isol_core")
  38. d0.If(name == "").Hassert("NewMonolit(): name is empty")
  39. kCtx := d2.GetKernCtx()
  40. opt := kCtx.Get(txtIsLocal)
  41. opt.Hassert("GetMonolit(): in get from kernCtx isLocal -- not found")
  42. isLocalCtx := opt.Some()
  43. isLocal := isLocalCtx.Val().(d0.Bool)
  44. lCtx := d1.NewLocalCtx(owner, kCtx.SelfCtx())
  45. sf := &LModMonolit{
  46. owner: owner,
  47. kCtx: kCtx,
  48. lCtx: lCtx,
  49. name: name,
  50. dict: map[mod_ent.AModuleName]mod_spec.IKernelModule{},
  51. isWork: d0.MutSafeBool(owner, false),
  52. isEnd: d0.MutSafeBool(owner, false),
  53. isLocal: d0.LetBool(owner, isLocal),
  54. }
  55. sf.log = sf.lCtx.Log()
  56. sf.kCtx.Set(d0.LetTxt(owner, "monolitName"), name, "name of monolit")
  57. sf.kCtx.Set(d0.LetTxt(owner, "monolit"), sf, "monolit-app")
  58. mon = sf
  59. _ = mod_spec.IKernelMonolit(sf)
  60. return sf
  61. }
  62. // Owner -- возвращает владельца монолита
  63. func (sf *LModMonolit) Owner() *d0.LOwner {
  64. return sf.owner
  65. }
  66. // Ctx -- возвращает контекст монолита.
  67. func (sf *LModMonolit) Ctx() *d1.LocalCtx {
  68. return sf.lCtx
  69. }
  70. // Log -- возвращает лог монолита.
  71. func (sf *LModMonolit) Log() *d1.LogBuf {
  72. return sf.lCtx.Log()
  73. }
  74. // Name -- возвращает имя монолита.
  75. func (sf *LModMonolit) Name() mod_ent.AModuleName {
  76. return sf.name
  77. }
  78. // Add -- добавляет модуль в монолит.
  79. func (sf *LModMonolit) Add(module mod_spec.IKernelModule) {
  80. sf.kCtx.RLock()
  81. defer sf.kCtx.RUnlock()
  82. d0.If(module == nil).Hassert("kMonolit.Add(): module==nil", []any{})
  83. _, isOk := sf.dict[module.Name().Get()]
  84. d0.If(d0.Bool(isOk)).Hassert("kMonolit.Add(): module(%v) already exists", []any{module.Name()})
  85. sf.dict[module.Name().Get()] = module
  86. sf.log.Debug("kMonolit.Add(): module='%v'", module.Name())
  87. if sf.isWork.IsOk() {
  88. go module.Run()
  89. sf.log.Debug("kMonolit.Add(): module='%v' is run", module.Name())
  90. }
  91. key := d0.LetTxt(owner, "module_%v", len(sf.dict))
  92. moduleName := module.Name()
  93. comment := d0.LetTxt(owner, "kMonolit.Add(): module="+moduleName.Txt())
  94. sf.lCtx.Set(key, module, comment.Get())
  95. }
  96. // Run -- запускает монолит в работу.
  97. func (sf *LModMonolit) Run() {
  98. sf.kCtx.RLock()
  99. defer sf.kCtx.RUnlock()
  100. if sf.isEnd.IsOk() {
  101. return
  102. }
  103. if sf.isWork.IsOk() {
  104. return
  105. }
  106. sf.isWork.Set()
  107. for _, module := range sf.dict {
  108. go module.Run()
  109. }
  110. sf.log.Debug("kMonolit.Run()")
  111. }
  112. // IsLocal -- возвращает признак локальной шины.
  113. func (sf *LModMonolit) IsLocal() *d0.LBool {
  114. return sf.isLocal
  115. }
  116. // IsWork -- возвращает признак работы монолита.
  117. func (sf *LModMonolit) IsWork() *d0.LBool {
  118. res := sf.isWork.Let()
  119. return res
  120. }
  121. // Ожидание завершения работы монолита.
  122. func (sf *LModMonolit) Wait() {
  123. sf.kCtx.Wait()
  124. sf.kCtx.Wg().Wait()
  125. sf.kCtx.Lock()
  126. defer sf.kCtx.Unlock()
  127. sf.isWork.Reset()
  128. sf.isEnd.Set()
  129. sf.log.Debug("kMonolit.close(): end")
  130. }