Add listener support to event service and notify on event creation
This commit is contained in:
+53
-1
@@ -3,23 +3,67 @@ package event
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
. "git.gorlug.de/code/ersteller"
|
||||
"git.gorlug.de/code/ersteller/schema/ent"
|
||||
)
|
||||
|
||||
type Listener interface {
|
||||
OnEvent(ctx context.Context, userId int, name string, data any)
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
entClient *ent.Client
|
||||
listeners []Listener
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
func NewService(entClient *ent.Client) *Service {
|
||||
return &Service{
|
||||
entClient: entClient,
|
||||
listeners: make([]Listener, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) AddListener(listener Listener) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.listeners = append(s.listeners, listener)
|
||||
}
|
||||
|
||||
func (s *Service) RemoveListener(listener Listener) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
for i, l := range s.listeners {
|
||||
if l == listener {
|
||||
s.listeners = append(s.listeners[:i], s.listeners[i+1:]...)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) notifyListeners(ctx context.Context, userId int, name string, data any) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
for _, listener := range s.listeners {
|
||||
go listener.OnEvent(ctx, userId, name, data)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) Create(htmxContext HtmxContext, name string, data any) error {
|
||||
return Create(s.entClient, htmxContext, name, data)
|
||||
err := Create(s.entClient, htmxContext, name, data)
|
||||
if err == nil {
|
||||
var userId int
|
||||
ok, authContext := htmxContext.GetAuthContext()
|
||||
if ok {
|
||||
userId = authContext.UserId
|
||||
} else {
|
||||
userId = -1
|
||||
}
|
||||
s.notifyListeners(htmxContext.GetGoContext(), userId, name, data)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func Should(err error) {
|
||||
@@ -39,6 +83,11 @@ func Create(entClient *ent.Client, c HtmxContext, name string, data any) error {
|
||||
|
||||
func CreateWithSession(entClient *ent.Client, ctx context.Context,
|
||||
auth AuthContext, name string, data any) error {
|
||||
return CreateWithSessionAndNotify(entClient, ctx, auth, name, data, nil)
|
||||
}
|
||||
|
||||
func CreateWithSessionAndNotify(entClient *ent.Client, ctx context.Context,
|
||||
auth AuthContext, name string, data any, service *Service) error {
|
||||
Debug("event", name, data)
|
||||
var mapData JSONB
|
||||
if data == nil {
|
||||
@@ -58,5 +107,8 @@ func CreateWithSession(entClient *ent.Client, ctx context.Context,
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create event: %w", err)
|
||||
}
|
||||
if service != nil {
|
||||
service.notifyListeners(ctx, auth.UserId, name, data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user