package serverevents import ( di "git.apihub24.de/admin/generic-di" "sync" "time" ) func init() { di.Injectable(newContext) } type IContext interface { SetId(id string) GetId() string Set(key string, data any) Get(key string) (any, bool) RemoveMetaData(key string) CleanupIn(lifetime time.Duration) Dispatch(eventName string, data any, filter func(c IContext) bool) IsCaller(c IContext) bool } type context struct { id string metadata map[string]any timer *time.Timer emitter IEventEmitter mutex sync.RWMutex } func newContext() IContext { return &context{ id: "", metadata: make(map[string]any), timer: nil, emitter: di.Inject[IEventEmitter](), mutex: sync.RWMutex{}, } } 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() if _, ok := context.metadata[key]; ok { 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(eventName string, data any, filter func(c IContext) bool) { ev := Event{ Type: eventName, Data: data, IsBackendOnly: filter == nil, Filter: filter, } context.emitter.Emit(ev) }