package core import ( "fmt" "time" lib "git.sr.ht/~cco/go-scopes" "git.sr.ht/~cco/go-scopes/config" "git.sr.ht/~cco/go-scopes/core/action" "git.sr.ht/~cco/go-scopes/logging" ) func Delayed(proc lib.Proc, delay time.Duration) lib.Proc { return func(ctx lib.Context) { logging.Debug(ctx).Int("delay", int(delay)).Msg("core.Delayed") time.Sleep(delay * time.Millisecond) proc(ctx) } } func None(_ lib.Context) {} func Start(ctx lib.Context) { logging.Debug(ctx).Msg("core.Start") lib.RunCtx(ctx, ctx.Config().Listener()) } func Listen(ctx lib.Context) { step := ctx.Config().Step() for step(ctx) { } } func Step(ctx lib.Context) (loop bool) { loop = true defer Recover(ctx, "core.Step") select { case msg := <-ctx.Mailbox(): loop = lib.HandleMsg(ctx, msg) case <-ctx.Done(): loop = ctx.Config().DoneHandler()(ctx) } return } func HandleMessage(ctx lib.Context, msg lib.Message) (loop bool) { loop = true logging.DebugM(ctx, msg).Msg("core.HandleMessage") for _, act := range action.Select(ctx, msg) { loop = act.Handle() } return } func HandleDone(ctx lib.Context) bool { return false } // Recover checks if there was a panic condition and recovers from it. // In this case the error is logged and returned. // Returns the error (or nil if there wasn't any). func Recover(ctx lib.Context, txt string) interface{} { err := recover() if err != nil { if estr, ok := err.(string); ok { err = fmt.Errorf(estr) } logging.Error(ctx, err.(error)).Msg(txt) } return err } func init() { config.DefaultStart = Start // avoid import cycle config.DefaultListen = Listen config.DefaultStep = Step config.DefaultMsgHandler = HandleMessage config.DefaultDoneHandler = HandleDone }