kmonolit.go 3.4 KB

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