132 lines
2.6 KiB
Go
132 lines
2.6 KiB
Go
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, onCleanup ...func())
|
|
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, onCleanup ...func()) {
|
|
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)
|
|
for _, cleaner := range onCleanup {
|
|
cleaner()
|
|
}
|
|
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
|
|
}
|