Actors/Packages/Redis/API reference
@sigx/actors-redis · Preview

API reference#

Exports of @sigx/actors-redis v0.1.0.

redisCluster(options)#

Returns ClusterProviders — membership and directory together. The common case.

TypeScript
cluster({ providers: redisCluster({ client }), advertise, secret });
TypeScript
interface RedisClusterOptions {
    client?: RedisClient;      // an ioredis instance
    url?: string;              // …or a URL to construct one
    namespace?: string;        // 'sigx'
    heartbeatMs?: number;      // 5000
    ttlMs?: number;            // 15000
    pollMs?: number;           // 5000
}

Call it once per host — each call returns that host's own membership handle.

redisMembership(client, options?)#

Membership alone: TTL heartbeats, a polled view with pub/sub push, and self-fencing when this host cannot renew past ttlMs.

redisDirectory(client, options?)#

The single-activation claim directory. Options: { namespace?: string }.

Pairs with any membership provider — notably k8sMembership().

redisStorage(options)#

An ActorStorage with etag compare-and-set.

TypeScript
defineActorApp({ storage: redisStorage({ client, namespace: 'sigx' }) });
TypeScript
interface RedisStorageOptions {
    client?: RedisClient;
    url?: string;
    namespace?: string;        // 'sigx' — share it with the cluster providers
}

Etags are client-minted UUIDs. save and clear compare-and-set atomically in Redis via Lua, registered as EVALSHA commands because save is the hot path, and throw the branded ActorStorageConflict on mismatch — which the runtime turns into discard-and-reload.

Types#

RedisClient (the ioredis Redis type), RedisClusterOptions, RedisStorageOptions.

Key layout#

{ns}:host:{hostId}    HASH {d: descriptor JSON}   PX ttlMs, renewed each beat
{ns}:hosts            SET of hostIds              lazily pruned
{ns}:mver             INCR'd version counter      cheap view-poll compare
{ns}:dir:{actorId}    "hostId\nactivationId"      no TTL (validity = owner liveness)
{ns}:membership       pub/sub channel             change push (poll = fallback)
{ns}:st:{type}\x00{key}   HASH {e: etag, s: state JSON}

The storage record key joins actor type and key with a NUL byte — the same actorId shape the directory uses. Redis keys are binary-safe, and a NUL renders invisibly in redis-cli SCAN output.

Directory entries carry no TTL: their validity is the owner's liveness, and entries for dead hosts are evicted lazily on lookup.

Operations used: the directory claim is SET NX GET; release and evict are Lua compare-and-delete; evictHost is a SCAN plus an owner-prefix delete.

Next steps#