Documentation
¶
Overview ¶
Package storage — Redis-backed store for Helix Cluster OS.
Key schema:
clusteros:cache:{k} – generic cache entries
clusteros:routing:{sessionID} – session routing hash (HSET)
clusteros:ratelimit:{subject} – rate-limit counter (user or "global")
clusteros:events:nodes – pub/sub channel for NodeEvent messages
Package storage provides a unified storage abstraction for Helix Cluster OS.
Index ¶
- Variables
- func CacheKey(k string) string
- func NodeEventsChannel() string
- func RateLimitKey(subject string) string
- func RoutingKey(sessionID string) string
- type FileStore
- type MemoryStore
- type NodeEvent
- type RedisStore
- func (r *RedisStore) GetSessionRouting(ctx context.Context, sessionID string) (map[string]string, error)
- func (r *RedisStore) PublishNodeEvent(ctx context.Context, evt NodeEvent) error
- func (r *RedisStore) SetSessionRouting(ctx context.Context, sessionID string, fields map[string]string, ...) error
- func (r *RedisStore) SubscribeNodeEvents(ctx context.Context) (<-chan NodeEvent, error)
- type S3Config
- type S3Store
- type SigV4Signer
- type Signer
- type Store
Constants ¶
This section is empty.
Variables ¶
var ( ErrEmptyKey = errors.New("key cannot be empty") ErrKeyNotFound = errors.New("key not found") // ErrUnsafeKey is returned by FileStore when a key would resolve to a path // outside the store root (e.g. a key containing "../"). Keys are opaque // strings in the Store contract, but FileStore maps them onto a filesystem // hierarchy; a traversing key must never be allowed to read, write, or // delete outside the configured root. ErrUnsafeKey = errors.New("key escapes store root") )
Functions ¶
func NodeEventsChannel ¶
func NodeEventsChannel() string
NodeEventsChannel returns the Redis pub/sub channel for node events.
func RateLimitKey ¶
RateLimitKey returns the full Redis key for a rate-limit counter.
func RoutingKey ¶
RoutingKey returns the full Redis key for a session routing hash.
Types ¶
type FileStore ¶
type FileStore struct {
// contains filtered or unexported fields
}
FileStore is a filesystem-backed Store implementation.
func NewFileStore ¶
NewFileStore creates a new FileStore rooted at the given directory.
type MemoryStore ¶
type MemoryStore struct {
// contains filtered or unexported fields
}
MemoryStore is an in-memory Store implementation.
func (*MemoryStore) Get ¶
func (s *MemoryStore) Get(key string) ([]byte, error)
Get retrieves data by key.
type NodeEvent ¶
type NodeEvent struct {
// Type is the event kind, e.g. "join", "leave", "update".
Type string `json:"type"`
// NodeID identifies the node that changed state.
NodeID string `json:"node_id"`
// Payload carries arbitrary per-event metadata.
Payload map[string]string `json:"payload,omitempty"`
}
NodeEvent represents a cluster-membership change published on the node-events channel. Fields are kept flat (JSON-serialisable) to stay wire-compatible with any subscriber.
type RedisStore ¶
type RedisStore struct {
// contains filtered or unexported fields
}
RedisStore provides session-routing, pub/sub, and cache helpers backed by Redis. Construct it with NewRedisStore (real go-redis client) or with newRedisStoreFromSeam (tests).
func NewRedisStore ¶
func NewRedisStore(addr string) (*RedisStore, error)
NewRedisStore creates a RedisStore wired to a real go-redis/v9 client. addr is the Redis address, e.g. "127.0.0.1:6379".
func (*RedisStore) GetSessionRouting ¶
func (r *RedisStore) GetSessionRouting(ctx context.Context, sessionID string) (map[string]string, error)
GetSessionRouting returns all fields from the routing hash for sessionID. A missing key returns an empty map and no error.
func (*RedisStore) PublishNodeEvent ¶
func (r *RedisStore) PublishNodeEvent(ctx context.Context, evt NodeEvent) error
PublishNodeEvent serialises evt as JSON and publishes it to clusteros:events:nodes.
func (*RedisStore) SetSessionRouting ¶
func (r *RedisStore) SetSessionRouting(ctx context.Context, sessionID string, fields map[string]string, ttl time.Duration) error
SetSessionRouting stores fields as a Redis hash at clusteros:routing:{sessionID} and sets its TTL. fields must be non-nil; ttl must be > 0.
func (*RedisStore) SubscribeNodeEvents ¶
func (r *RedisStore) SubscribeNodeEvents(ctx context.Context) (<-chan NodeEvent, error)
SubscribeNodeEvents returns a channel that delivers deserialised NodeEvents published on clusteros:events:nodes. The channel is closed when ctx is cancelled or the underlying subscription is torn down.
type S3Config ¶
type S3Config struct {
// Endpoint is the S3 service base URL (scheme+host[+path]), WITHOUT the
// bucket. Required.
Endpoint string
// Bucket is the target bucket name. Required.
Bucket string
// Signer signs each request. Required (use a SigV4Signer for real S3).
Signer Signer
// Client is the HTTP client to use. Nil means http.DefaultClient.
Client *http.Client
}
S3Config configures an S3Store.
type S3Store ¶
type S3Store struct {
// contains filtered or unexported fields
}
S3Store is an S3-compatible object-storage Store implementation. It speaks the S3 REST API directly over net/http (no aws-sdk) and signs every request with the configured Signer (SigV4 by default). Objects are addressed as {endpoint}/{bucket}/{key}; keys are used verbatim as object paths.
func NewS3Store ¶
NewS3Store constructs an S3Store. It validates required fields so a misconfigured store fails loudly at construction rather than on first call.
func (*S3Store) Delete ¶
Delete removes {bucket}/{key}. S3 returns 204 whether or not the object existed, which matches the idempotent-delete contract of the other stores.
func (*S3Store) Exists ¶
Exists reports whether {bucket}/{key} exists, via a HEAD request. This is an additive convenience beyond the Store interface.
type SigV4Signer ¶
type SigV4Signer struct {
AccessKeyID string
SecretAccessKey string
SessionToken string // optional; emitted as x-amz-security-token when set
Region string
Service string // "s3" for object storage
// contains filtered or unexported fields
}
SigV4Signer implements AWS Signature Version 4 (HMAC-SHA256) over net/http. It is stdlib-only and deterministic given a fixed clock, which is what makes the pinned-vector test possible.
func (*SigV4Signer) Sign ¶
func (s *SigV4Signer) Sign(req *http.Request, payloadHash string) error
Sign computes the SigV4 Authorization header for req and sets it, along with the x-amz-date and x-amz-content-sha256 headers. payloadHash must be the lowercase hex SHA-256 of the exact bytes that will be sent as the body.
type Signer ¶
Signer signs an outgoing S3 HTTP request in place, adding the Authorization header (and any required x-amz-* headers). It is a pluggable seam so callers can swap in alternative auth (e.g. STS session tokens, anonymous) without touching S3Store. payloadHash is the lowercase hex SHA-256 of the request body, which the signer must fold into the canonical request.