kctx.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // package kctx -- контекст ядра
  2. package kctx
  3. import (
  4. "context"
  5. "fmt"
  6. "sync"
  7. . "gitp78su.ipnodns.ru/svi/kern/v4/lev0/ktypes"
  8. . "gitp78su.ipnodns.ru/svi/kern/v4/lev1"
  9. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kernel_keeper"
  10. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kwg"
  11. )
  12. // kCtx -- контекст ядра
  13. type kCtx struct {
  14. ILocalCtx
  15. log ILogBuf
  16. ctxBg context.Context // Неотменяемый контекст ядра
  17. ctx context.Context // Отменяемый контекст ядра
  18. fnCancel func() // Функция отмены контекста ядра
  19. kernKeeper IKernelKeeper // Встроенный сторож отмены контекста системным сигналом
  20. kernWg IKernelWg // Встроенный ожидатель потока
  21. }
  22. var (
  23. kernCtx *kCtx // Глобальный объект контекста приложения
  24. block sync.Mutex
  25. )
  26. // GetKernelCtx -- возвращает контекст ядра
  27. func GetKernelCtx() IResult[*kCtx] {
  28. block.Lock()
  29. defer block.Unlock()
  30. if kernCtx != nil {
  31. return NewRes(kernCtx)
  32. }
  33. ctxBg := context.Background()
  34. ctx, fnCancel := context.WithCancel(ctxBg)
  35. sf := &kCtx{
  36. ctxBg: ctxBg,
  37. ctx: ctx,
  38. fnCancel: fnCancel,
  39. }
  40. resLocal := NewLocalCtx(sf.ctx)
  41. if resLocal.IsErr() {
  42. err := fmt.Errorf("GetKernelCtx(): in get local ctx, err=\n\t%w", resLocal.Err())
  43. return NewErr[*kCtx](err)
  44. }
  45. sf.ILocalCtx = resLocal.Val()
  46. sf.log = sf.Log()
  47. sf.kernWg = kwg.GetKernelWg(sf.ctx)
  48. resKeep := kernel_keeper.GetKernelKeeper(sf.ctx, sf.fnCancel, sf.kernWg)
  49. if resKeep.IsErr() {
  50. sf.log.Err("GetKernelCtx(): in get kernel keeper, err=\n\t%w", resKeep.Err())
  51. return nil
  52. }
  53. sf.kernKeeper = resKeep.Val()
  54. kernCtx = sf
  55. return NewRes(kernCtx)
  56. }
  57. // Keeper -- возвращает сторож системных сигналов
  58. func (sf *kCtx) Keeper() IKernelKeeper {
  59. return sf.kernKeeper
  60. }
  61. // Wg -- возвращает ожидатель потоков
  62. func (sf *kCtx) Wg() IKernelWg {
  63. return sf.kernWg
  64. }
  65. // Done -- блокирующий вызов ожидания отмены контекста ядра
  66. func (sf *kCtx) Done() {
  67. <-sf.ctx.Done()
  68. sf.log.Debug("kCtx.Done()")
  69. }
  70. // CtxBg -- возвращает неотменяемый контекст ядра (лучше не использовать)
  71. func (sf *kCtx) CtxBg() context.Context {
  72. return sf.ctxBg
  73. }
  74. // Cancel -- отменяет контекст ядра
  75. func (sf *kCtx) Cancel() {
  76. sf.fnCancel()
  77. sf.log.Debug("kCtx.Cancel()")
  78. }