feat: rewrite bus to prevent deadlocks
This commit is contained in:
@ -5,7 +5,7 @@ import (
|
||||
|
||||
"forge.cadoles.com/arcad/edge/pkg/app"
|
||||
"forge.cadoles.com/arcad/edge/pkg/bus"
|
||||
edgeHTTP "forge.cadoles.com/arcad/edge/pkg/http"
|
||||
edgehttp "forge.cadoles.com/arcad/edge/pkg/http"
|
||||
"forge.cadoles.com/arcad/edge/pkg/module"
|
||||
"forge.cadoles.com/arcad/edge/pkg/module/util"
|
||||
"github.com/dop251/goja"
|
||||
@ -38,10 +38,9 @@ func (m *Module) broadcast(call goja.FunctionCall, rt *goja.Runtime) goja.Value
|
||||
}
|
||||
|
||||
data := call.Argument(0).Export()
|
||||
ctx := context.Background()
|
||||
|
||||
msg := module.NewServerMessage(ctx, data)
|
||||
if err := m.bus.Publish(ctx, msg); err != nil {
|
||||
env := edgehttp.NewOutgoingMessageEnvelope("", data)
|
||||
if err := m.bus.Publish(env); err != nil {
|
||||
panic(rt.ToValue(errors.WithStack(err)))
|
||||
}
|
||||
|
||||
@ -53,38 +52,33 @@ func (m *Module) send(call goja.FunctionCall, rt *goja.Runtime) goja.Value {
|
||||
panic(rt.ToValue(errors.New("invalid number of argument")))
|
||||
}
|
||||
|
||||
var ctx context.Context
|
||||
|
||||
firstArg := call.Argument(0)
|
||||
|
||||
sessionID, ok := firstArg.Export().(string)
|
||||
if ok {
|
||||
ctx = module.WithContext(context.Background(), map[module.ContextKey]any{
|
||||
edgeHTTP.ContextKeySessionID: sessionID,
|
||||
})
|
||||
} else {
|
||||
ctx = util.AssertContext(firstArg, rt)
|
||||
if !ok {
|
||||
ctx := util.AssertContext(firstArg, rt)
|
||||
sessionID = module.ContextValue[string](ctx, edgehttp.ContextKeySessionID)
|
||||
}
|
||||
|
||||
data := call.Argument(1).Export()
|
||||
|
||||
msg := module.NewServerMessage(ctx, data)
|
||||
if err := m.bus.Publish(ctx, msg); err != nil {
|
||||
env := edgehttp.NewOutgoingMessageEnvelope(sessionID, data)
|
||||
if err := m.bus.Publish(env); err != nil {
|
||||
panic(rt.ToValue(errors.WithStack(err)))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Module) handleClientMessages() {
|
||||
func (m *Module) handleIncomingMessages() {
|
||||
ctx := context.Background()
|
||||
|
||||
logger.Debug(
|
||||
ctx,
|
||||
"subscribing to bus messages",
|
||||
"subscribing to bus envelopes",
|
||||
)
|
||||
|
||||
clientMessages, err := m.bus.Subscribe(ctx, module.MessageNamespaceClient)
|
||||
envelopes, err := m.bus.Subscribe(ctx, edgehttp.AddressIncomingMessage)
|
||||
if err != nil {
|
||||
panic(errors.WithStack(err))
|
||||
}
|
||||
@ -92,16 +86,16 @@ func (m *Module) handleClientMessages() {
|
||||
defer func() {
|
||||
logger.Debug(
|
||||
ctx,
|
||||
"unsubscribing from bus messages",
|
||||
"unsubscribing from bus envelopes",
|
||||
)
|
||||
|
||||
m.bus.Unsubscribe(ctx, module.MessageNamespaceClient, clientMessages)
|
||||
m.bus.Unsubscribe(edgehttp.AddressIncomingMessage, envelopes)
|
||||
}()
|
||||
|
||||
for {
|
||||
logger.Debug(
|
||||
ctx,
|
||||
"waiting for next message",
|
||||
"waiting for next envelope",
|
||||
)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@ -112,13 +106,13 @@ func (m *Module) handleClientMessages() {
|
||||
|
||||
return
|
||||
|
||||
case msg := <-clientMessages:
|
||||
clientMessage, ok := msg.(*module.ClientMessage)
|
||||
case env := <-envelopes:
|
||||
incomingMessage, ok := env.Message().(*edgehttp.IncomingMessage)
|
||||
if !ok {
|
||||
logger.Warn(
|
||||
ctx,
|
||||
"unexpected message type",
|
||||
logger.F("message", msg),
|
||||
logger.F("message", env.Message()),
|
||||
)
|
||||
|
||||
continue
|
||||
@ -126,11 +120,11 @@ func (m *Module) handleClientMessages() {
|
||||
|
||||
logger.Debug(
|
||||
ctx,
|
||||
"received client message",
|
||||
logger.F("message", clientMessage),
|
||||
"received incoming message",
|
||||
logger.F("message", incomingMessage),
|
||||
)
|
||||
|
||||
if _, err := m.server.ExecFuncByName(clientMessage.Context, "onClientMessage", clientMessage.Context, clientMessage.Data); err != nil {
|
||||
if _, err := m.server.ExecFuncByName(incomingMessage.Context, "onClientMessage", incomingMessage.Context, incomingMessage.Payload); err != nil {
|
||||
if errors.Is(err, app.ErrFuncDoesNotExist) {
|
||||
continue
|
||||
}
|
||||
@ -152,7 +146,7 @@ func ModuleFactory(bus bus.Bus) app.ServerModuleFactory {
|
||||
bus: bus,
|
||||
}
|
||||
|
||||
go module.handleClientMessages()
|
||||
go module.handleIncomingMessages()
|
||||
|
||||
return module
|
||||
}
|
||||
|
Reference in New Issue
Block a user