kmonolit.go 3.8 KB

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