package context import ( stdlib_context "context" "fmt" "sync" "time" lib "git.sr.ht/~cco/go-scopes" ) type Context = lib.Context type ContextState = lib.ContextState type Services = lib.Services type context struct { cfg lib.Config parent Context children []Context state ContextState mailbox chan lib.Message } func (ctx *context) Config() lib.Config { return ctx.cfg } func (ctx *context) Name() string { return ctx.cfg.Name() } func (ctx *context) Parent() lib.Context { return ctx.parent } func (ctx *context) Services() Services { return ctx.parent.Services() } func (ctx *context) ChildContext(cfg lib.Config) Context { cctx := makeCtx(cfg, ctx) ctx.children = append(ctx.children, cctx) name := cfg.Name() if name == "" { cfg.SetName(fmt.Sprintf("%s.%d", ctx.Name(), len(ctx.children))) } else { ctx.Services()[name] = cctx } return cctx } func (ctx *context) State() ContextState { return ctx.state } func (ctx *context) WithState(state ContextState) Context { ctx.state = state return ctx } func (ctx *context) Mailbox() chan lib.Message { return ctx.mailbox } func (ctx *context) WaitGroup() *sync.WaitGroup { return ctx.parent.WaitGroup() } func (ctx *context) Done() <-chan struct{} { return ctx.parent.Done() } func (ctx *context) Send(msg lib.Message) { ctx.Mailbox() <- msg } func (ctx *context) Stop() { // ctx.Warn("Only application-level service can be stopped } func makeCtx(cfg lib.Config, parent Context) *context { return &context{ cfg: cfg, parent: parent, mailbox: make(chan lib.Message, 10), } } // interface Addressable func (ctx *context) Cell() Context { return ctx } func (ctx *context) Address() lib.Address { return nil } // implement interface context.Context from standard library func (ctx *context) Deadline() (deadline time.Time, ok bool) { return time.Time{}, false } func (ctx *context) Err() error { select { case _, ok := <-ctx.Done(): if !ok { return stdlib_context.Canceled } default: return nil } return nil } func (ctx *context) Value(key interface{}) interface{} { return nil }