Compare commits

..

No commits in common. "main" and "v2.0.2" have entirely different histories.
main ... v2.0.2

16 changed files with 86 additions and 204 deletions

View File

@ -2,11 +2,10 @@ package serverevents
import ( import (
gocontext "context" gocontext "context"
"sync"
"time"
di "git.apihub24.de/admin/generic-di" di "git.apihub24.de/admin/generic-di"
"github.com/coder/websocket" "github.com/coder/websocket"
"sync"
"time"
) )
func init() { func init() {
@ -21,8 +20,8 @@ type IContext interface {
Set(key string, data any) Set(key string, data any)
Get(key string) (any, bool) Get(key string) (any, bool)
RemoveMetaData(key string) RemoveMetaData(key string)
CleanupIn(lifetime time.Duration, onCleanup ...func()) CleanupIn(lifetime time.Duration)
Dispatch(event IEvent, filter func(c IContext) bool) Dispatch(eventName string, data any, filter func(c IContext) bool)
IsCaller(c IContext) bool IsCaller(c IContext) bool
} }
@ -85,10 +84,12 @@ func (context *context) RemoveMetaData(key string) {
context.mutex.Lock() context.mutex.Lock()
defer context.mutex.Unlock() defer context.mutex.Unlock()
if _, ok := context.metadata[key]; ok {
delete(context.metadata, key) delete(context.metadata, key)
} }
}
func (context *context) CleanupIn(lifetime time.Duration, onCleanup ...func()) { func (context *context) CleanupIn(lifetime time.Duration) {
context.mutex.Lock() context.mutex.Lock()
defer context.mutex.Unlock() defer context.mutex.Unlock()
@ -104,18 +105,15 @@ func (context *context) CleanupIn(lifetime time.Duration, onCleanup ...func()) {
if context.timer != nil { if context.timer != nil {
di.Destroy[IContext](context.id) di.Destroy[IContext](context.id)
for _, cleaner := range onCleanup {
cleaner()
}
context.timer = nil context.timer = nil
} }
}(context.id) }(context.id)
} }
func (context *context) Dispatch(event IEvent, filter func(c IContext) bool) { func (context *context) Dispatch(eventName string, data any, filter func(c IContext) bool) {
ev := Event{ ev := Event{
Type: event.GetEventName(), Type: eventName,
Data: event.GetEventData(), Data: data,
IsBackendOnly: filter == nil, IsBackendOnly: filter == nil,
Filter: filter, Filter: filter,
} }

View File

@ -1,7 +1,5 @@
package serverevents package serverevents
import "encoding/json"
func CreateMetaDataFilter[T any](c IContext, metaDataSelector func(IContext) T, vgl func(a T, b T) bool) func(context IContext) bool { func CreateMetaDataFilter[T any](c IContext, metaDataSelector func(IContext) T, vgl func(a T, b T) bool) func(context IContext) bool {
return func(context IContext) bool { return func(context IContext) bool {
metaA := metaDataSelector(c) metaA := metaDataSelector(c)
@ -17,13 +15,9 @@ func MetadataAs[T any](context IContext, key string) (T, bool) {
func ValueAs[T any](data any) (T, bool) { func ValueAs[T any](data any) (T, bool) {
var v T var v T
str, err := json.Marshal(data) if data == nil {
if err != nil {
return v, false return v, false
} }
err = json.Unmarshal(str, &v) res, ok := data.(T)
if err != nil { return res, ok
return v, false
}
return v, true
} }

View File

@ -6,8 +6,3 @@ type Event struct {
IsBackendOnly bool `json:"-"` IsBackendOnly bool `json:"-"`
Filter func(c IContext) bool `json:"-"` Filter func(c IContext) bool `json:"-"`
} }
type IEvent interface {
GetEventName() string
GetEventData() any
}

View File

@ -1,7 +1,6 @@
package serverevents package serverevents
type IEventHandler interface { type IEventHandler interface {
GetConnectedEventName() string
CanExecute(IContext) bool CanExecute(IContext) bool
Handle(IContext, any) Handle(IContext, any)
} }

View File

@ -1,5 +0,0 @@
package dto
type Greeting struct {
Message string `json:"message"`
}

View File

@ -1,26 +0,0 @@
package definitions
import (
serverevents "git.apihub24.de/admin/server_events/v2"
"git.apihub24.de/admin/server_events/v2/implementation_test/data/dto"
)
const GreeterEventName = "greet"
type greetEvent struct {
data dto.Greeting
}
func NewGreetEvent(data dto.Greeting) serverevents.IEvent {
return &greetEvent{
data: data,
}
}
func (ev *greetEvent) GetEventName() string {
return GreeterEventName
}
func (ev *greetEvent) GetEventData() any {
return ev.data
}

View File

@ -1,23 +0,0 @@
package definitions
import serverevents "git.apihub24.de/admin/server_events/v2"
const GreetMeEventName = "greet me"
type greetMeEvent struct {
data string
}
func NewGreetMeEvent(name string) serverevents.IEvent {
return &greetMeEvent{
data: name,
}
}
func (ev *greetMeEvent) GetEventName() string {
return GreetMeEventName
}
func (ev *greetMeEvent) GetEventData() any {
return ev.data
}

View File

@ -1,19 +0,0 @@
package definitions
import serverevents "git.apihub24.de/admin/server_events/v2"
const PingEventName = "ping"
type pingEvent struct{}
func NewPingEvent() serverevents.IEvent {
return &pingEvent{}
}
func (ev *pingEvent) GetEventName() string {
return PingEventName
}
func (ev *pingEvent) GetEventData() any {
return nil
}

View File

@ -1,19 +0,0 @@
package definitions
import serverevents "git.apihub24.de/admin/server_events/v2"
const PongEventName = "pong"
type pongEvent struct{}
func NewPongEvent() serverevents.IEvent {
return &pongEvent{}
}
func (ev *pongEvent) GetEventName() string {
return PongEventName
}
func (ev *pongEvent) GetEventData() any {
return nil
}

View File

@ -0,0 +1,39 @@
package events
import (
"fmt"
serverevents "git.apihub24.de/admin/server_events/v2"
)
func withSameUserName(context serverevents.IContext) func(context serverevents.IContext) bool {
return serverevents.CreateMetaDataFilter(context, func(c serverevents.IContext) string {
userName, _ := serverevents.MetadataAs[string](context, "UserName")
return userName
}, func(a string, b string) bool {
return a == b
})
}
type greeting struct {
Message string
}
type greeterEventHandler struct{}
func (handler greeterEventHandler) CanExecute(_ serverevents.IContext) bool {
return true
}
func (handler greeterEventHandler) Handle(context serverevents.IContext, data any) {
userName, ok := serverevents.ValueAs[string](data)
if !ok || len(userName) < 1 {
userName = "Anonymous"
}
context.Dispatch("greet", greeting{
Message: fmt.Sprintf("Hello, %s", userName),
}, withSameUserName(context))
}
func NewGreeterEventHandler() serverevents.IEventHandler {
return &greeterEventHandler{}
}

View File

@ -1,34 +0,0 @@
package handler
import (
"fmt"
serverevents "git.apihub24.de/admin/server_events/v2"
"git.apihub24.de/admin/server_events/v2/implementation_test/data/dto"
"git.apihub24.de/admin/server_events/v2/implementation_test/events/definitions"
"git.apihub24.de/admin/server_events/v2/implementation_test/filter"
)
type greetMeEventHandler struct{}
func NewGreetMeEventHandler() serverevents.IEventHandler {
return &greetMeEventHandler{}
}
func (handler *greetMeEventHandler) GetConnectedEventName() string {
return definitions.GreetMeEventName
}
func (handler *greetMeEventHandler) CanExecute(_ serverevents.IContext) bool {
return true
}
func (handler *greetMeEventHandler) Handle(context serverevents.IContext, data any) {
userName, ok := serverevents.ValueAs[string](data)
if !ok || len(userName) < 1 {
userName = "Anonymous"
}
context.Dispatch(definitions.NewGreetEvent(dto.Greeting{
Message: fmt.Sprintf("Hello, %s", userName),
}), filter.WithSameUserName(context))
}

View File

@ -1,24 +0,0 @@
package handler
import (
serverevents "git.apihub24.de/admin/server_events/v2"
"git.apihub24.de/admin/server_events/v2/implementation_test/events/definitions"
)
type pingEventHandler struct{}
func NewPingEventHandler() serverevents.IEventHandler {
return &pingEventHandler{}
}
func (handler *pingEventHandler) GetConnectedEventName() string {
return definitions.PingEventName
}
func (handler *pingEventHandler) CanExecute(_ serverevents.IContext) bool {
return true
}
func (handler *pingEventHandler) Handle(context serverevents.IContext, _ any) {
context.Dispatch(definitions.NewPongEvent(), context.IsCaller)
}

View File

@ -0,0 +1,19 @@
package events
import (
serverevents "git.apihub24.de/admin/server_events/v2"
)
type pingEventHandler struct{}
func NewPingEventHandler() serverevents.IEventHandler {
return &pingEventHandler{}
}
func (p pingEventHandler) CanExecute(_ serverevents.IContext) bool {
return true
}
func (p pingEventHandler) Handle(context serverevents.IContext, _ any) {
context.Dispatch("pong", nil, context.IsCaller)
}

View File

@ -1,12 +0,0 @@
package filter
import serverevents "git.apihub24.de/admin/server_events/v2"
func WithSameUserName(context serverevents.IContext) func(context serverevents.IContext) bool {
return serverevents.CreateMetaDataFilter(context, func(c serverevents.IContext) string {
userName, _ := serverevents.MetadataAs[string](context, "UserName")
return userName
}, func(a string, b string) bool {
return a == b
})
}

View File

@ -1,21 +1,20 @@
package main package main
import ( import (
di "git.apihub24.de/admin/generic-di"
serverevents "git.apihub24.de/admin/server_events/v2"
"git.apihub24.de/admin/server_events/v2/implementation_test/events"
"log" "log"
"net/http" "net/http"
"time" "time"
di "git.apihub24.de/admin/generic-di"
serverevents "git.apihub24.de/admin/server_events/v2"
"git.apihub24.de/admin/server_events/v2/implementation_test/events/handler"
) )
func main() { func main() {
serverEventsMiddleware := di.Inject[serverevents.IMiddleware]() serverEventsMiddleware := di.Inject[serverevents.IMiddleware]()
eventRegistration := di.Inject[serverevents.IEventHandlerRegistration]() eventRegistration := di.Inject[serverevents.IEventHandlerRegistration]()
eventRegistration.Use(handler.NewPingEventHandler) eventRegistration.Add("ping", events.NewPingEventHandler)
eventRegistration.Use(handler.NewGreetMeEventHandler) eventRegistration.Add("greet me", events.NewGreeterEventHandler)
router := http.NewServeMux() router := http.NewServeMux()

View File

@ -2,9 +2,8 @@ package serverevents
import ( import (
"fmt" "fmt"
"sync"
di "git.apihub24.de/admin/generic-di" di "git.apihub24.de/admin/generic-di"
"sync"
) )
func init() { func init() {
@ -12,7 +11,7 @@ func init() {
} }
type IEventHandlerRegistration interface { type IEventHandlerRegistration interface {
Use(creator func() IEventHandler) Add(eventType string, creator func() IEventHandler)
GetHandler(eventType string) (IEventHandler, error) GetHandler(eventType string) (IEventHandler, error)
} }
@ -30,14 +29,16 @@ func newEventHandlerRegistration() IEventHandlerRegistration {
} }
} }
func (registration *eventHandlerRegistration) Use(creator func() IEventHandler) { func (registration *eventHandlerRegistration) Add(eventType string, creator func() IEventHandler) {
registration.mutex.Lock() registration.mutex.Lock()
defer registration.mutex.Unlock() defer registration.mutex.Unlock()
tmp := creator() if _, ok := registration.instances[eventType]; ok {
eventType := tmp.GetConnectedEventName()
delete(registration.instances, eventType) delete(registration.instances, eventType)
}
if _, ok := registration.creators[eventType]; ok {
delete(registration.creators, eventType) delete(registration.creators, eventType)
}
registration.creators[eventType] = creator registration.creators[eventType] = creator
} }