kmonolit.go 3.2 KB

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