kmonolit.go 3.6 KB

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