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 (
gocontext "context"
"sync"
"time"
di "git.apihub24.de/admin/generic-di"
"github.com/coder/websocket"
"sync"
"time"
)
func init() {
@ -21,8 +20,8 @@ type IContext interface {
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)
CleanupIn(lifetime time.Duration)
Dispatch(eventName string, data any, filter func(c IContext) bool)
IsCaller(c IContext) bool
}
@ -85,10 +84,12 @@ func (context *context) RemoveMetaData(key string) {
context.mutex.Lock()
defer context.mutex.Unlock()
delete(context.metadata, key)
if _, ok := context.metadata[key]; ok {
delete(context.metadata, key)
}
}
func (context *context) CleanupIn(lifetime time.Duration, onCleanup ...func()) {
func (context *context) CleanupIn(lifetime time.Duration) {
context.mutex.Lock()
defer context.mutex.Unlock()
@ -104,18 +105,15 @@ func (context *context) CleanupIn(lifetime time.Duration, onCleanup ...func()) {
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) {
func (context *context) Dispatch(eventName string, data any, filter func(c IContext) bool) {
ev := Event{
Type: event.GetEventName(),
Data: event.GetEventData(),
Type: eventName,
Data: data,
IsBackendOnly: filter == nil,
Filter: filter,
}

View File

@ -1,7 +1,5 @@
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 {
return func(context IContext) bool {
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) {
var v T
str, err := json.Marshal(data)
if err != nil {
if data == nil {
return v, false
}
err = json.Unmarshal(str, &v)
if err != nil {
return v, false
}
return v, true
res, ok := data.(T)
return res, ok
}

View File

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

View File

@ -1,7 +1,6 @@
package serverevents
type IEventHandler interface {
GetConnectedEventName() string
CanExecute(IContext) bool
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
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"
"net/http"
"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() {
serverEventsMiddleware := di.Inject[serverevents.IMiddleware]()
eventRegistration := di.Inject[serverevents.IEventHandlerRegistration]()
eventRegistration.Use(handler.NewPingEventHandler)
eventRegistration.Use(handler.NewGreetMeEventHandler)
eventRegistration.Add("ping", events.NewPingEventHandler)
eventRegistration.Add("greet me", events.NewGreeterEventHandler)
router := http.NewServeMux()

View File

@ -2,9 +2,8 @@ package serverevents
import (
"fmt"
"sync"
di "git.apihub24.de/admin/generic-di"
"sync"
)
func init() {
@ -12,7 +11,7 @@ func init() {
}
type IEventHandlerRegistration interface {
Use(creator func() IEventHandler)
Add(eventType string, creator func() IEventHandler)
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()
defer registration.mutex.Unlock()
tmp := creator()
eventType := tmp.GetConnectedEventName()
delete(registration.instances, eventType)
delete(registration.creators, eventType)
if _, ok := registration.instances[eventType]; ok {
delete(registration.instances, eventType)
}
if _, ok := registration.creators[eventType]; ok {
delete(registration.creators, eventType)
}
registration.creators[eventType] = creator
}