UNPKG

@rivetkit/redis

Version:

_Lightweight Libraries for Backends_

92 lines (80 loc) 2.68 kB
import type { GenericConnGlobalState, RegistryConfig, RunConfig, } from "@rivetkit/core"; import type { ActorDriver, AnyActorInstance, ManagerDriver, } from "@rivetkit/core/driver-helpers"; import invariant from "invariant"; import type Redis from "ioredis"; import type { RedisDriverConfig } from "./config"; import { ActorPeer } from "./coordinate/actor-peer"; import type { Node } from "./coordinate/node/mod"; import type { GlobalState } from "./coordinate/types"; import { KEYS } from "./keys"; import { logger } from "./log"; // Define AnyClient locally since it's not exported type AnyClient = any; export interface DriverContext { redis: Redis; keyPrefix: string; } /** * Redis implementation of the Actor Driver */ export class RedisActorDriver implements ActorDriver { #globalState: GlobalState; #redis: Redis; #driverConfig: RedisDriverConfig; constructor( globalState: GlobalState, redis: Redis, driverConfig: RedisDriverConfig, ) { this.#globalState = globalState; this.#redis = redis; this.#driverConfig = driverConfig; } async loadActor(actorId: string): Promise<AnyActorInstance> { const actor = await ActorPeer.getLeaderActor(this.#globalState, actorId); invariant(actor, `Actor ${actorId} is not the leader on this node`); return actor; } getGenericConnGlobalState(actorId: string): GenericConnGlobalState { const peer = ActorPeer.getLeaderActorPeer(this.#globalState, actorId); invariant(peer, `Actor ${actorId} is not the leader on this node`); return peer.genericConnGlobalState; } getContext(_actorId: string): DriverContext { return { redis: this.#redis, keyPrefix: this.#driverConfig.keyPrefix }; } async readPersistedData(actorId: string): Promise<Uint8Array | undefined> { const data = await this.#redis.getBuffer( KEYS.ACTOR.persistedData(this.#driverConfig.keyPrefix, actorId), ); if (data !== null) return data; return undefined; } async writePersistedData(actorId: string, data: Uint8Array): Promise<void> { await this.#redis.set( KEYS.ACTOR.persistedData(this.#driverConfig.keyPrefix, actorId), Buffer.from(data), ); } async setAlarm(actor: AnyActorInstance, timestamp: number): Promise<void> { logger().warn( "redis driver currently does not support scheduling. alarms are currently implemented with setTimeout and will not survive sleeping.replaced with setTimeout.", { issue: "https://github.com/rivet-gg/rivetkit/issues/1095" }, ); const delay = Math.max(timestamp - Date.now(), 0); setTimeout(() => { actor.onAlarm(); }, delay); } getDatabase(actorId: string): Promise<unknown | undefined> { return Promise.resolve(undefined); } }