fix to only call cb for session id who initiated the event

This commit is contained in:
maddalax 2024-10-16 14:35:02 -05:00
parent 64fd4cfeab
commit 278161782c
4 changed files with 51 additions and 57 deletions

View file

@ -1,16 +1,13 @@
package event
import (
"crypto/sha256"
"fmt"
"github.com/google/uuid"
"github.com/maddalax/htmgo/framework/h"
"github.com/maddalax/htmgo/framework/service"
"github.com/puzpuzpuz/xsync/v3"
"runtime"
"sse-with-state/sse"
"sse-with-state/state"
"strings"
"sync"
"sync/atomic"
"time"
@ -41,35 +38,6 @@ var serverSideMessageListener = make(chan ServerSideEvent, 100)
var lock = sync.Mutex{}
var callingHandler = atomic.Bool{}
func getCallerHash() string {
pc := make([]uintptr, 1000) // Adjust the size if you need a deeper stack trace
n := runtime.Callers(2, pc) // Skip 2: runtime.Callers() and printCallers()
frames := runtime.CallersFrames(pc[:n])
calls := make([]string, 0)
hitBegin := false
for {
frame, more := frames.Next()
calls = append(calls, fmt.Sprintf("%s:%d", frame.Function, frame.Line))
if strings.Contains(frame.Function, "runtime.goexit") {
hitBegin = true
}
if !more {
break
}
}
if !hitBegin {
fmt.Printf("hitBegin: %v\n", hitBegin)
panic("unable to add handler, stack trace too deep, maximum 1000, unable to find runtime.goexit")
}
joined := strings.Join(calls, ",")
hash := sha256.Sum256([]byte(joined))
return fmt.Sprintf("%x", hash)
}
func AddServerSideHandler(ctx *h.RequestContext, event string, handler Handler) *h.AttributeMapOrdered {
// If we are already in a handler, we don't want to add another handler
// this can happen if the handler renders another element that has a handler
@ -104,11 +72,11 @@ func storeHashForSession(sessionId state.SessionId, hash KeyHash) {
m[hash] = true
}
func PushServerSideEvent(sessionId state.SessionId, event string) {
func PushServerSideEvent(data HandlerData, event string, value map[string]any) {
serverSideMessageListener <- ServerSideEvent{
Event: event,
Payload: make(map[string]any),
SessionId: sessionId,
Payload: value,
SessionId: data.SessionId,
}
}
@ -134,22 +102,38 @@ func StartListener(locator *service.Locator) {
select {
case sevent := <-serverSideMessageListener:
fmt.Printf("received server side event: %s\n", sevent.Event)
// TODO optimize this
hashes, ok := serverEventNamesToHash.Load(sevent.Event)
if ok {
for hash := range hashes {
hashesForSession, ok2 := sessionIdToHashes.Load(sevent.SessionId)
subset := make(map[KeyHash]bool)
for hash := range hashes {
if _, ok := hashesForSession[hash]; ok {
subset[hash] = true
}
}
if ok && ok2 {
lock.Lock()
callingHandler.Store(true)
wg := sync.WaitGroup{}
for hash := range subset {
cb, ok := handlers.Load(hash)
if ok {
lock.Lock()
callingHandler.Store(true)
cb(HandlerData{
SessionId: sevent.SessionId,
Socket: manager.Get(string(sevent.SessionId)),
Manager: manager,
})
callingHandler.Store(false)
lock.Unlock()
wg.Add(1)
go func(e ServerSideEvent) {
defer wg.Done()
cb(HandlerData{
SessionId: e.SessionId,
Socket: manager.Get(string(e.SessionId)),
Manager: manager,
})
}(sevent)
}
}
wg.Wait()
callingHandler.Store(false)
lock.Unlock()
}
case event := <-socketMessageListener:

View file

@ -3,6 +3,7 @@ package pages
import (
"fmt"
"github.com/maddalax/htmgo/framework/h"
"sse-with-state/event"
"sse-with-state/partials"
"sse-with-state/state"
)
@ -21,6 +22,12 @@ func IndexPage(ctx *h.RequestContext) *h.Page {
partials.Repeater(ctx, partials.RepeaterProps{
Id: "repeater-1",
OnAdd: func(data event.HandlerData) {
event.PushServerSideEvent(data, "increment", map[string]any{})
},
OnRemove: func(data event.HandlerData, index int) {
event.PushServerSideEvent(data, "decrement", map[string]any{})
},
AddButton: h.Button(
h.Text("+ Add Item"),
),

View file

@ -19,6 +19,7 @@ func UseState[T any](sessionId state.SessionId, key string, initial T) (func() T
type Counter struct {
Count func() int
Increment func()
Decrement func()
}
func UseCounter(sessionId state.SessionId, id string) Counter {
@ -28,9 +29,14 @@ func UseCounter(sessionId state.SessionId, id string) Counter {
set(get() + 1)
}
var decrement = func() {
set(get() - 1)
}
return Counter{
Count: get,
Increment: increment,
Decrement: decrement,
}
}
@ -66,16 +72,10 @@ func CounterForm(ctx *h.RequestContext, props CounterProps) *h.Element {
counter.Increment()
event.PushElement(data, CounterForm(ctx, props))
}),
//OnMouseOver(ctx, func(data event.HandlerData) {
// counter.Increment()
// updated := CounterForm(ctx, props)
// event.PushElement(data, updated)
//}),
//OnClick(ctx, func(data event.HandlerData) {
// counter.Increment()
// updated := CounterForm(ctx, props)
// event.PushElement(data, updated)
//}),
OnServerSideEvent(ctx, "decrement", func(data event.HandlerData) {
counter.Decrement()
event.PushElement(data, CounterForm(ctx, props))
}),
),
)
}

View file

@ -13,6 +13,8 @@ type RepeaterProps struct {
DefaultItems []*h.Element
Id string
currentIndex int
OnAdd func(data event.HandlerData)
OnRemove func(data event.HandlerData, index int)
}
func (props *RepeaterProps) itemId(index int) string {
@ -33,6 +35,7 @@ func repeaterItem(ctx *h.RequestContext, item *h.Element, index int, props *Repe
h.ClassIf(index == 0, "opacity-0 disabled"),
h.If(index == 0, h.Disabled()),
OnClick(ctx, func(data event.HandlerData) {
props.OnRemove(data, index)
props.currentIndex--
event.PushElement(data,
h.Div(
@ -59,7 +62,7 @@ func Repeater(ctx *h.RequestContext, props RepeaterProps) *h.Element {
h.Class("flex justify-center"),
props.AddButton,
OnClick(ctx, func(data event.HandlerData) {
event.PushServerSideEvent(data.SessionId, "increment")
props.OnAdd(data)
event.PushElement(data,
h.Div(
h.Attribute("hx-swap-oob", "beforebegin:#"+props.addButtonId()),