fix to only call cb for session id who initiated the event
This commit is contained in:
parent
64fd4cfeab
commit
278161782c
4 changed files with 51 additions and 57 deletions
|
|
@ -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,23 +102,39 @@ 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 {
|
||||
hashesForSession, ok2 := sessionIdToHashes.Load(sevent.SessionId)
|
||||
|
||||
subset := make(map[KeyHash]bool)
|
||||
for hash := range hashes {
|
||||
cb, ok := handlers.Load(hash)
|
||||
if ok {
|
||||
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 {
|
||||
wg.Add(1)
|
||||
go func(e ServerSideEvent) {
|
||||
defer wg.Done()
|
||||
cb(HandlerData{
|
||||
SessionId: sevent.SessionId,
|
||||
Socket: manager.Get(string(sevent.SessionId)),
|
||||
SessionId: e.SessionId,
|
||||
Socket: manager.Get(string(e.SessionId)),
|
||||
Manager: manager,
|
||||
})
|
||||
}(sevent)
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
callingHandler.Store(false)
|
||||
lock.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case event := <-socketMessageListener:
|
||||
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()),
|
||||
|
|
|
|||
Loading…
Reference in a new issue