Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Session ¶
type Session interface {
Id() string
Get(key string) any
String(key string) string
Set(key string, value any)
Has(key string) bool
Delete(key string)
Clear()
All() map[string]any
IsModified() bool
IsCleared() bool
/* Snapshot answers the values, the modified flag and the cleared flag read under ONE critical section. The response path decides between deleting and saving a session from these three, and reading them through the individual accessors lets a concurrent Clear land between the reads: the decision then pairs a pre-logout flag with post-logout values — or saves a session the caller was just told is gone — while both calls report success. */
Snapshot() (values map[string]any, modified bool, cleared bool)
}
type Storage ¶
type Storage interface {
Load(sessionId string) (map[string]any, bool, error)
Save(sessionId string, data map[string]any, ttl time.Duration) error
Delete(sessionId string) error
Close() error
}
Storage is where sessions are kept, and an implementation must be safe for concurrent use: the manager serialises Save and Delete through a lock striped by session id, so two writes naming the SAME session never overlap, while Load runs under no manager lock at all and writes naming different sessions usually run concurrently — a storage behind a network is exactly why they must, since one lock for the whole manager would put every session write in the process behind one round trip. Both storages melody ships take a mutex of their own; one written over redis or a database has the same obligation, per session id at the least. The manager's refusal to re-save a deleted session is a per-process guarantee, not the storage's to keep: the tombstone lives in the manager's memory, so a storage shared between instances receives the Save that a peer instance's tombstone would have refused.