use Addressable interface for generic Send() and action receivers

This commit is contained in:
Helmut Merz 2023-07-25 10:41:48 +02:00
parent fbff96dcc0
commit e55ce25190
5 changed files with 33 additions and 22 deletions

View file

@ -59,7 +59,7 @@ func (t *T) TearDownApp(name string) {
// give actors time to recieve all messages: // give actors time to recieve all messages:
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
//t.Check() //t.Check()
lib.Send(t.Ctx, message.SimpleAddress(name), message.Quit) message.Send(t.Ctx, message.SimpleAddress(name), message.Quit)
t.Ctx.WaitGroup().Wait() t.Ctx.WaitGroup().Wait()
//t.AssertNoUncheckedMessages() //t.AssertNoUncheckedMessages()
} }

View file

@ -10,19 +10,23 @@ type BaseSpec = baseSpec
type baseSpec struct { type baseSpec struct {
handler lib.ActionHandler handler lib.ActionHandler
receivers []string receivers []lib.Addressable
} }
func (spec *baseSpec) Handler() lib.ActionHandler { func (spec *baseSpec) Handler() lib.ActionHandler {
return spec.handler return spec.handler
} }
func (spec *baseSpec) Receivers() []string { func (spec *baseSpec) Receivers() []lib.Addressable {
return spec.receivers return spec.receivers
} }
func Base(hdlr lib.ActionHandler, rcvrs ...string) *baseSpec { func Base(hdlr lib.ActionHandler, rcvs ...string) *baseSpec {
return &baseSpec{hdlr, rcvrs} spec := baseSpec{handler: hdlr}
for _, rcv := range rcvs {
spec.receivers = append(spec.receivers, message.SimpleAddress(rcv))
}
return &spec
} }
// action selection // action selection
@ -89,9 +93,8 @@ func (act *action) Handle() bool {
func Forward(act lib.Action) bool { func Forward(act lib.Action) bool {
ctx := act.Context() ctx := act.Context()
msg := act.Message() msg := act.Message()
for _, rcvr := range act.Spec().Receivers() { for _, rcv := range act.Spec().Receivers() {
addr := message.SimpleAddress(rcvr) message.Send(ctx, rcv, msg)
lib.Send(ctx, addr, msg)
} }
return true return true
} }

View file

@ -2,9 +2,11 @@ package message
import ( import (
"encoding/json" "encoding/json"
"fmt"
"strings" "strings"
lib "git.sr.ht/~cco/go-scopes" lib "git.sr.ht/~cco/go-scopes"
"git.sr.ht/~cco/go-scopes/logging"
"git.sr.ht/~cco/go-scopes/logging/log" "git.sr.ht/~cco/go-scopes/logging/log"
) )
@ -124,3 +126,20 @@ func PayloadFromJson[T any](s string) lib.Payload {
pl := &payload{new(T)} pl := &payload{new(T)}
return pl.FromJson(s) return pl.FromJson(s)
} }
// generic send functionality
func Send(ctx lib.Context, rcv lib.Addressable, msg lib.Message) {
if msg.Sender() == nil {
msg.WithSender(ctx)
}
if cell := rcv.Cell(); cell != nil {
cell.Send(msg)
} else if svc, ok := ctx.Services()[rcv.Address().Service()]; ok {
// TODO: check Address for sid, iid
svc.Send(msg)
} else {
logging.WarnM(ctx, msg).
Msg(fmt.Sprintf("scopes.Send: invalid address: %+v", rcv))
}
}

View file

@ -82,7 +82,7 @@ type Action interface {
type ActionSpec interface { type ActionSpec interface {
Handler() ActionHandler Handler() ActionHandler
Receivers() []string Receivers() []Addressable
} }
// procedures and handlers // procedures and handlers
@ -132,17 +132,6 @@ func HandleMsg(ctx Context, msg Message) bool {
return ctx.Config().MessageHandler()(ctx, msg) return ctx.Config().MessageHandler()(ctx, msg)
} }
func Send(ctx Context, addr Address, msg Message) {
if msg.Sender() == nil {
msg.WithSender(ctx)
}
if svc, ok := ctx.Services()[addr.Service()]; ok {
// TODO: check Address for sid, iid
svc.Send(msg)
}
// TODO: Warn().Msg("receiver not found")
}
func GetState[St ContextState](ctx Context) St { func GetState[St ContextState](ctx Context) St {
return ctx.State().(St) return ctx.State().(St)
} }

View file

@ -38,14 +38,14 @@ func SendTest(t *testing.T) {
ctx := t.Ctx ctx := t.Ctx
rcvr := message.SimpleAddress("testing") rcvr := message.SimpleAddress("testing")
msg := message.SimpleMessage("demo") msg := message.SimpleMessage("demo")
lib.Send(ctx, rcvr, msg) message.Send(ctx, rcvr, msg)
} }
func ClientTest(t *testing.T) { func ClientTest(t *testing.T) {
ctx := t.Ctx ctx := t.Ctx
rcvr := message.SimpleAddress("test-client") rcvr := message.SimpleAddress("test-client")
msg := message.SimpleMessage("demo") msg := message.SimpleMessage("demo")
lib.Send(ctx, rcvr, msg) message.Send(ctx, rcvr, msg)
} }
// action handlers // action handlers