server_events/v2/context.go
2025-07-06 21:28:31 +02:00

115 lines
2.2 KiB
Go

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)
}