| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- // package kmonolit -- модульный монолит на основе ядра.
- package kmonolit
- import (
- "sync"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev0/core_spec"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev0/etypes/ebool"
- mKh "gitp78su.ipnodns.ru/svi/kern/v4/lev0/helpers"
- mL1 "gitp78su.ipnodns.ru/svi/kern/v4/lev1"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev1/comp_spec"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kctx"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kspec"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev3/mod_ent"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev3/mod_spec"
- )
- // kMonolit -- объект модульного монолита.
- type kMonolit struct {
- kCtx kspec.IKernelCtx
- lCtx comp_spec.ILocalCtx
- log comp_spec.ILogBuf
- name mod_ent.AModuleName
- isLocal core_spec.EBool
- isWork core_spec.ISafeBool
- isEnd core_spec.ISafeBool
- dict map[mod_ent.AModuleName]mod_spec.IKernelModule // Словарь модулей монолита
- }
- var (
- mon *kMonolit
- block sync.Mutex
- )
- var (
- txtIsLocal = defs.Txt("isLocal")
- msg1 = defs.Txt("GetMonolit(): in get from kernCtx isLocal -- not found")
- )
- // GetMonolit -- возвращает монолит.
- func GetMonolit(name mod_ent.AModuleName) *kMonolit {
- block.Lock()
- defer block.Unlock()
- if mon != nil {
- return mon
- }
- mKh.Hassert(name != "", "NewMonolit(): name is empty")
- kCtx := kctx.GetKernelCtx()
- opt := kCtx.Get(txtIsLocal)
- opt.Hassert(msg1)
- isLocalCtx := opt.Some()
- isLocal := isLocalCtx.Val().(bool)
- lCtx := mL1.NewLocalCtx(kCtx.Ctx())
- sf := &kMonolit{
- kCtx: kCtx,
- lCtx: lCtx,
- name: name,
- dict: map[mod_ent.AModuleName]mod_spec.IKernelModule{},
- isWork: mL1.NewSafeBool(false),
- isEnd: mL1.NewSafeBool(false),
- isLocal: ebool.NewEBool(isLocal),
- }
- sf.log = sf.lCtx.Log()
- sf.kCtx.Set(defs.Txt("monolitName"), name, defs.Txt("name of monolit"))
- sf.kCtx.Set(defs.Txt("monolit"), sf, defs.Txt("monolit-app"))
- mon = sf
- _ = mod_spec.IKernelMonolit(sf)
- return sf
- }
- // Ctx -- возвращает контекст монолита.
- func (sf *kMonolit) Ctx() comp_spec.ILocalCtx {
- return sf.lCtx
- }
- // Log -- возвращает лог монолита.
- func (sf *kMonolit) Log() comp_spec.ILogBuf {
- return sf.lCtx.Log()
- }
- // Name -- возвращает имя монолита.
- func (sf *kMonolit) Name() mod_ent.AModuleName {
- return sf.name
- }
- // Add -- добавляет модуль в монолит.
- func (sf *kMonolit) Add(module mod_spec.IKernelModule) {
- sf.kCtx.RLock()
- defer sf.kCtx.RUnlock()
- mKh.Hassert(module != nil, "kMonolit.Add(): module==nil", []any{})
- _, isOk := sf.dict[module.Name().Get()]
- mKh.Hassert(!isOk, "kMonolit.Add(): module(%v) already exists", []any{module.Name()})
- sf.dict[module.Name().Get()] = module
- sf.log.Debug(defs.Txt("kMonolit.Add(): module='%v'", module.Name()))
- if sf.isWork.Get() {
- go module.Run()
- sf.log.Debug(defs.Txt("kMonolit.Add(): module='%v' is run", module.Name()))
- }
- key := defs.Txt("module_%v", len(sf.dict))
- moduleName := module.Name()
- comment := defs.Txt("kMonolit.Add(): module=" + moduleName.Txt().Get())
- sf.lCtx.Set(key, module, comment)
- }
- // Run -- запускает монолит в работу.
- func (sf *kMonolit) Run() {
- sf.kCtx.RLock()
- defer sf.kCtx.RUnlock()
- if sf.isEnd.Get() {
- return
- }
- if sf.isWork.Get() {
- return
- }
- sf.isWork.Set()
- for _, module := range sf.dict {
- go module.Run()
- }
- sf.log.Debug(defs.Txt("kMonolit.Run()"))
- }
- // IsLocal -- возвращает признак локальной шины.
- func (sf *kMonolit) IsLocal() core_spec.EBool {
- return sf.isLocal
- }
- // IsWork -- возвращает признак работы монолита.
- func (sf *kMonolit) IsWork() core_spec.EBool {
- res := sf.isWork.Get()
- return ebool.NewEBool(res)
- }
- // Ожидание завершения работы монолита.
- func (sf *kMonolit) Wait() {
- sf.kCtx.Wait()
- sf.kCtx.Wg().Wait()
- sf.kCtx.Lock()
- defer sf.kCtx.Unlock()
- sf.isWork.Reset()
- sf.isEnd.Set()
- sf.log.Debug(defs.Txt("kMonolit.close(): end"))
- }
|