kmonolit.go 3.6 KB

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