package serverevents import ( gocontext "context" "sync" "time" di "git.apihub24.de/admin/generic-di" "github.com/coder/websocket" ) func init() { di.Injectable(newContext) } type IContext interface { SetId(id string) GetId() string SetConnection(conn *websocket.Conn) GetConnection() *websocket.Conn Set(key string, data any) Get(key string) (any, bool) RemoveMetaData(key string) CleanupIn(lifetime time.Duration) Dispatch(event IEvent, filter func(c IContext) bool) IsCaller(c IContext) bool } type context struct { id string metadata map[string]any timer *time.Timer hub IEventHub mutex sync.RWMutex c *websocket.Conn ctx gocontext.Context } func newContext() IContext { return &context{ id: "", metadata: make(map[string]any), timer: nil, hub: di.Inject[IEventHub](), mutex: sync.RWMutex{}, c: nil, } } func (context *context) SetId(id string) { context.mutex.Lock() defer context.mutex.Unlock() if context.timer != nil { context.timer.Stop() context.timer = nil } context.id = id } func (context *context) GetId() string { return context.id } func (context *context) IsCaller(c IContext) bool { return context.id == c.GetId() } func (context *context) Set(key string, data any) { context.mutex.Lock() defer context.mutex.Unlock() context.metadata[key] = data } func (context *context) Get(key string) (any, bool) { context.mutex.RLock() defer context.mutex.RUnlock() v, ok := context.metadata[key] return v, ok } func (context *context) RemoveMetaData(key string) { context.mutex.Lock() defer context.mutex.Unlock() delete(context.metadata, key) } func (context *context) CleanupIn(lifetime time.Duration) { context.mutex.Lock() defer context.mutex.Unlock() if context.timer != nil { context.timer.Stop() } context.timer = time.NewTimer(lifetime) go func(currentId string) { <-context.timer.C context.mutex.Lock() defer context.mutex.Unlock() if context.timer != nil { di.Destroy[IContext](context.id) context.timer = nil } }(context.id) } func (context *context) Dispatch(event IEvent, filter func(c IContext) bool) { ev := Event{ Type: event.GetEventName(), Data: event.GetEventData(), IsBackendOnly: filter == nil, Filter: filter, } context.hub.Dispatch(ev, context) } func (context *context) GetConnection() *websocket.Conn { return context.c } func (context *context) SetConnection(conn *websocket.Conn) { context.c = conn }