go-scopes/scopes.go

137 lines
2.3 KiB
Go

// Package `scopes` provides a set of common types (mostly interfaces
// and function declarations) and some basic functions.
package scopes
import (
stdlib_context "context"
"fmt"
"sync"
)
// config
type ActionSpec interface {
Handler() ActionHandler
Receivers() []string
}
type Pattern interface {
fmt.Stringer
Slice() []string
}
type ActionConfig interface {
Pattern() Pattern
Specs() []ActionSpec
}
type Config interface {
Name() string
Starter() StartProc
Step() StepProc
MessageHandler() MessageHandler
DoneHandler() StepProc
Actions() []ActionConfig
AddAction(string, ...ActionSpec) Config
Children() []Config
Add(...Config) Config
}
// services - context
type Services map[string]Context
type ContextState interface{}
type Context interface {
stdlib_context.Context
Config() Config
Parent() Context
Services() Services
ChildContext(Config) Context
State() ContextState
WithState(ContextState) Context
Mailbox() chan Message
WaitGroup() *sync.WaitGroup
Stop()
}
// message, address
type MsgHead interface {
fmt.Stringer
Slice() []string
Domain() string
Action() string
Class() string
Item() string
}
type Message interface {
MsgHead
Head() MsgHead
Sender() Address
Payload() Payload
WithSender(Address) Message
WithPayload(Payload) Message
}
type Address interface {
fmt.Stringer
Url() string
Service() string
Interaction() (string, string)
SetUrl(string)
SetInteraction(string, string)
}
type Payload interface {
fmt.Stringer
Data() interface{}
FromJson(string) Payload
}
// action
type Action interface {
Context() Context
Spec() ActionSpec
Message() Message
Handle() bool
}
// procedures and handlers
type Proc = func(Context)
type StartProc = Proc
type StepProc = func(Context) bool
type MessageHandler = func(Context, Message) bool
type ActionHandler = func(Action) bool
// library functions
func RunCtx(ctx Context, fct Proc) {
ctx.WaitGroup().Add(1)
go func() {
defer ctx.WaitGroup().Done()
fct(ctx)
}()
}
func HandleMsg(ctx Context, msg Message) bool {
return ctx.Config().MessageHandler()(ctx, msg)
}
func Send(ctx Context, addr Address, msg Message) {
if srv, ok := ctx.Services()[addr.Service()]; ok {
srv.Mailbox() <- msg
}
}
func GetState[St ContextState](ctx Context) St {
return ctx.State().(St)
}
func GetCfg[C Config](ctx Context) C {
return ctx.Config().(C)
}