edge/pkg/module/lifecycle.go

192 lines
3.7 KiB
Go
Raw Permalink Normal View History

2023-02-09 12:16:36 +01:00
package module
import (
"context"
"forge.cadoles.com/arcad/edge/pkg/app"
"forge.cadoles.com/arcad/edge/pkg/bus"
"github.com/dop251/goja"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
type LifecycleModule struct {
backend *app.Backend
bus bus.Bus
}
func (m *LifecycleModule) Name() string {
return "lifecycle"
}
func (m *LifecycleModule) Export(export *goja.Object) {
}
func (m *LifecycleModule) OnInit() error {
if _, err := m.backend.ExecFuncByName("onInit"); err != nil {
if errors.Is(err, app.ErrFuncDoesNotExist) {
logger.Warn(context.Background(), "could not find onInit() function", logger.E(errors.WithStack(err)))
return errors.WithStack(err)
}
}
return nil
}
func (m *LifecycleModule) handleMessages() {
ctx := context.Background()
logger.Debug(
ctx,
"subscribing to bus messages",
)
userConnectedMessages, err := m.bus.Subscribe(ctx, MessageNamespaceUserConnected)
if err != nil {
panic(errors.WithStack(err))
}
userDisconnectedMessages, err := m.bus.Subscribe(ctx, MessageNamespaceUserDisconnected)
if err != nil {
panic(errors.WithStack(err))
}
frontendMessageMessages, err := m.bus.Subscribe(ctx, MessageNamespaceFrontend)
if err != nil {
panic(errors.WithStack(err))
}
defer func() {
logger.Debug(
ctx,
"unsubscribing from bus messages",
)
m.bus.Unsubscribe(ctx, MessageNamespaceFrontend, frontendMessageMessages)
m.bus.Unsubscribe(ctx, MessageNamespaceUserDisconnected, userDisconnectedMessages)
m.bus.Unsubscribe(ctx, MessageNamespaceUserConnected, userConnectedMessages)
}()
for {
logger.Debug(
ctx,
"waiting for next message",
)
select {
case <-ctx.Done():
logger.Debug(
ctx,
"context done",
)
return
case msg := <-userConnectedMessages:
userConnected, ok := msg.(*UserConnectedMessage)
if !ok {
logger.Error(
ctx,
"unexpected message type",
logger.F("message", msg),
)
continue
}
logger.Debug(
ctx,
"received user connected message",
logger.F("message", userConnected),
)
if _, err := m.backend.ExecFuncByName("onUserConnect"); err != nil {
if errors.Is(err, app.ErrFuncDoesNotExist) {
continue
}
logger.Error(
ctx,
"on user connected error",
logger.E(err),
)
}
case msg := <-userDisconnectedMessages:
userDisconnected, ok := msg.(*UserDisconnectedMessage)
if !ok {
logger.Error(
ctx,
"unexpected message type",
logger.F("message", msg),
)
continue
}
logger.Debug(
ctx,
"received user disconnected message",
logger.F("message", userDisconnected),
)
if _, err := m.backend.ExecFuncByName("onUserDisconnect"); err != nil {
if errors.Is(err, app.ErrFuncDoesNotExist) {
continue
}
logger.Error(
ctx,
"on user disconnected error",
logger.E(err),
)
}
case msg := <-frontendMessageMessages:
frontendMessage, ok := msg.(*FrontendMessage)
if !ok {
logger.Error(
ctx,
"unexpected message type",
logger.F("message", msg),
)
continue
}
logger.Debug(
ctx,
"received frontend message",
logger.F("message", frontendMessage),
)
if _, err := m.backend.ExecFuncByName("onUserMessage", frontendMessage.Data); err != nil {
if errors.Is(err, app.ErrFuncDoesNotExist) {
continue
}
logger.Error(
ctx,
"on user message error",
logger.E(err),
)
}
}
}
}
func LifecycleModuleFactory(bus bus.Bus) app.BackendModuleFactory {
return func(backend *app.Backend) app.BackendModule {
module := &LifecycleModule{
backend: backend,
bus: bus,
}
go module.handleMessages()
return module
}
}
var _ app.InitializableModule = &LifecycleModule{}