valkey

package
v1.76.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 13, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package valkey is the Valkey driver of the legacy adapter (internal/port/legacy): the connection, its failover handling, and the one State that the issuer's logins in progress, the hub's snapshots and the refresh leases are all kept in.

Business code does not import it: it names the ports of internal/port.

Nothing here is a source of truth. Everything in this store can be rebuilt by reading the directory again, which is what makes it safe to lose: an empty cache is a hub with no snapshots, which answers "not authoritative" until the next refresh, and a non-authoritative answer removes nobody's access.

Index

Constants

View Source
const DefaultTTL = 7 * 24 * time.Hour

DefaultTTL is how long a snapshot outlives its last write.

It is not the freshness window — that is the hub's, and much shorter. This is only so that a workspace disconnected while a replica was down does not leave a copy of a company's directory sitting in a cache for ever.

Variables

This section is empty.

Functions

func Revision

func Revision(value []byte) string

Revision is what State calls a value's version: the SHA-256 of its bytes. It is a content tag, not a counter -- Valkey keeps no version of a key, and adding one would change what is written -- and it lives only in the process that read the value, between that read and the conditional write that follows: it is never stored. The comparison with the live value is made in Go, and the script then re-checks the bytes themselves.

Types

type Config

type Config struct {
	// Address is host:port. Empty means "no Valkey": the caller keeps
	// snapshots in memory instead.
	Address string
	// Password is optional.
	Password string
	// TLS turns on TLS to the server.
	TLS bool
	// Cluster speaks the cluster protocol. The fleet's Valkeys are
	// ValkeyClusters even at one shard, so this is the usual answer; a
	// plain single server needs it off, and a mismatch shows up as a
	// refused command at start rather than as a subtle failure later.
	Cluster bool
	// Prefix namespaces every key, so that one Valkey can serve more than
	// one installation.
	Prefix string
	// TTL overrides DefaultTTL.
	TTL time.Duration
}

Config is how to reach the Valkey the deployment points at.

type Entry

type Entry struct {
	Key string
	// Set is true for a set; Members is then its members and Value is nil.
	Set     bool
	Value   []byte
	Members []string
	// TTL is the remaining lifetime; 0 is none.
	TTL time.Duration
}

Entry is one key as State.Dump reads it: a string value or a set of members, with what is left of its lifetime.

type Outcome

type Outcome int

Outcome is what a conditional write did.

const (
	// Gone: there was no live value to compare.
	Gone Outcome = -1
	// Moved: the value's revision was not the one expected.
	Moved Outcome = 0
	// Done: the condition held and the command ran.
	Done Outcome = 1
)

The outcomes of State.Swap and State.DropIf.

type State

type State struct {
	// contains filtered or unexported fields
}

State is a login in progress, shared by every replica: the authorization request a browser is part-way through, the code it comes back with, the tokens that follow, the device flow a CLI is polling.

It is here rather than in the issuer because the issuer must not know what a cache is, and here rather than beside the snapshots because the two have nothing to do with each other beyond the address they dial. Everything carries its own expiry, so nothing sweeps.

func NewState

func NewState(client redis.UniversalClient, prefix string) *State

NewState wraps a client that is already open. For tests.

func OpenState

func OpenState(ctx context.Context, cfg Config) (*State, error)

OpenState connects and proves it can talk, so that a misconfigured address is a startup failure rather than a failed login.

func (*State) Add

func (s *State) Add(ctx context.Context, key, member string, ttl time.Duration) error

Add implements issuer.State.

SADD then EXPIRE, and the expiry is refreshed on every add: a set of sessions should outlive its newest member, not its oldest. Without the refresh an identity that signs in daily would have its whole index vanish on the anniversary of its first login.

func (*State) Close

func (s *State) Close() error

Close releases the connections.

func (*State) Delete

func (s *State) Delete(ctx context.Context, key string) error

Delete implements issuer.State.

func (*State) DropIf

func (s *State) DropIf(ctx context.Context, key, expected string) (Outcome, error)

DropIf deletes the value at key only if its Revision is expected.

func (*State) Dump

func (s *State) Dump(ctx context.Context, prefix string) ([]Entry, error)

Dump reads every key that starts with prefix, strings and sets, with the lifetime each has left, sorted by key. A key of another type is skipped, and one that expires between the scan and the read is gone. It is a SCAN, for an operator and not a request: it is what `sluis migrate` copies a login state with.

func (*State) Get

func (s *State) Get(ctx context.Context, key string) ([]byte, bool, error)

Get implements issuer.State.

func (*State) Keys

func (s *State) Keys(ctx context.Context, prefix string) ([]string, error)

Keys lists the keys that start with prefix, sorted, without this State's own namespace. It is a SCAN of every primary: right for a listing an operator or a watcher asks for, and not a path a request takes.

func (*State) Members

func (s *State) Members(ctx context.Context, key string) ([]string, error)

Members implements issuer.State.

func (*State) Ping

func (s *State) Ping(ctx context.Context) error

Ping reports whether the store answers. See [Snapshots.Ping] for why this is readiness and never liveness.

func (*State) Remove

func (s *State) Remove(ctx context.Context, key, member string) error

Remove implements issuer.State.

func (*State) Set

func (s *State) Set(ctx context.Context, key string, value []byte, ttl time.Duration) error

Set implements issuer.State.

func (*State) SetIfAbsent

func (s *State) SetIfAbsent(
	ctx context.Context, key string, value []byte, ttl time.Duration,
) (bool, error)

SetIfAbsent implements issuer.State.

func (*State) Swap

func (s *State) Swap(ctx context.Context, key, expected string, value []byte, ttl time.Duration) (Outcome, error)

Swap replaces the value at key with a new one for ttl, only if the current value's Revision is expected. It is one script, so two replicas swapping from one revision cannot both win.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL