htmgo/examples/sse-with-state/state/state.go

64 lines
1.4 KiB
Go
Raw Normal View History

2024-10-08 17:48:28 +00:00
package state
import (
2024-10-09 14:57:51 +00:00
"fmt"
2024-10-08 17:48:28 +00:00
"github.com/maddalax/htmgo/framework/h"
"github.com/puzpuzpuz/xsync/v3"
2024-10-09 14:57:51 +00:00
"sse-with-state/internal"
2024-10-08 17:48:28 +00:00
)
type SessionId string
var cache = xsync.NewMapOf[SessionId, *xsync.MapOf[string, any]]()
type State struct {
SessionId SessionId
}
func NewState(ctx *h.RequestContext) *State {
id := GetSessionId(ctx)
cache.Store(id, xsync.NewMapOf[string, any]())
return &State{
SessionId: id,
}
}
func GetSessionId(ctx *h.RequestContext) SessionId {
2024-10-09 14:57:51 +00:00
sessionIdRaw := ctx.Get("session-id")
2024-10-08 17:48:28 +00:00
sessionId := ""
2024-10-09 14:57:51 +00:00
if sessionIdRaw == "" || sessionIdRaw == nil {
sessionId = fmt.Sprintf("session-id-%s", internal.RandSeq(30))
ctx.Set("session-id", sessionId)
} else {
sessionId = sessionIdRaw.(string)
2024-10-08 17:48:28 +00:00
}
return SessionId(sessionId)
}
func Update[T any](sessionId SessionId, key string, compute func(prev T) T) T {
actual := Get[T](sessionId, key, *new(T))
next := compute(actual)
Set(sessionId, key, next)
return next
}
func Get[T any](sessionId SessionId, key string, fallback T) T {
actual, _ := cache.LoadOrCompute(sessionId, func() *xsync.MapOf[string, any] {
return xsync.NewMapOf[string, any]()
})
value, exists := actual.Load(key)
if exists {
return value.(T)
}
return fallback
}
func Set(sessionId SessionId, key string, value any) {
actual, _ := cache.LoadOrCompute(sessionId, func() *xsync.MapOf[string, any] {
return xsync.NewMapOf[string, any]()
})
actual.Store(key, value)
}