go-scopes/core/core.go

79 lines
1.7 KiB
Go

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
}