Documentation
¶
Overview ¶
Package postgres provides a store.SessionStore backed by PostgreSQL via github.com/jackc/pgx/v5. It is the recommended shared store for clustered deployments: every node points at the same database, so session state is durable and visible regardless of which cluster member rehydrates a internal/actor.SessionActor.
Optimistic concurrency on store.Snapshot.Version is enforced by a single statement (INSERT … ON CONFLICT … DO UPDATE … WHERE), so the version check and the write are atomic with respect to other writers without any explicit transaction or row-level locking.
State and History columns are JSONB. The encoder uses encoding/json, so atto's [session] types round-trip cleanly. The pgx connection pool is supplied by the caller (or constructed by Open) and must outlive every Store method call.
Index ¶
- Constants
- type Option
- type Store
- func (s *Store) Close()
- func (s *Store) Delete(ctx context.Context, sessionID string) error
- func (s *Store) EnsureSchema(ctx context.Context) error
- func (s *Store) Load(ctx context.Context, sessionID string) (*store.Snapshot, error)
- func (s *Store) Save(ctx context.Context, sessionID string, snap *store.Snapshot) error
Constants ¶
const DefaultTable = "atto_sessions"
DefaultTable is the table name used when the caller does not override it via WithTable. Override only if it would collide with an existing schema; otherwise prefer the default.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is a PostgreSQL-backed store.SessionStore.
func NewWithPool ¶
NewWithPool wraps an externally owned pgxpool.Pool. The store does NOT close pool on Store.Close; lifetime is the caller's responsibility.
func Open ¶
Open constructs a Store backed by a fresh pgxpool.Pool built from dsn. The store owns the pool and closes it on Store.Close.
For applications that already manage a pool, prefer NewWithPool to share the pool with the rest of the application.
func (*Store) Close ¶
func (s *Store) Close()
Close releases the pool when the store owns it. When the pool was supplied via NewWithPool this method is a no-op so the caller's pool keeps running.
func (*Store) Delete ¶
Delete implements store.SessionStore.Delete. Removing an absent row is a no-op per the store.SessionStore contract.
func (*Store) EnsureSchema ¶
EnsureSchema creates the sessions table when it does not exist. Safe to call repeatedly; CREATE TABLE IF NOT EXISTS is idempotent. Run it once at application startup before any Store.Save or Store.Load call.
func (*Store) Load ¶
Load implements store.SessionStore.Load.
func (*Store) Save ¶
Save implements store.SessionStore.Save. The version check, the update, and the insert are a single atomic statement: INSERT … ON CONFLICT … DO UPDATE … WHERE. A conflict whose stored version is not strictly less than the supplied version causes the update to be filtered out and the statement to affect zero rows; the store returns store.ErrConcurrentWrite in that case.