kmonolit.go 4.0 KB

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