Skip to content

Commit ae31640

Browse files
committed
chore: add ManagerDriver.findOrCreateWithKey
1 parent f69b2ca commit ae31640

File tree

14 files changed

+351
-326
lines changed

14 files changed

+351
-326
lines changed

packages/actor-core/src/driver-helpers/mod.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { ToServer } from "@/actor/protocol/message/to-server";
2-
31
export { type DriverConfig, DriverConfigSchema } from "./config";
42
export type { ActorInstance, AnyActorInstance } from "@/actor/instance";
53
export {
@@ -13,9 +11,9 @@ export {
1311
export { ActorDriver } from "@/actor/driver";
1412
export {
1513
ManagerDriver,
16-
CreateActorInput,
17-
CreateActorOutput,
18-
GetActorOutput,
14+
CreateInput,
1915
GetForIdInput,
2016
GetWithKeyInput,
17+
GetOrCreateWithKeyInput,
18+
ActorOutput,
2119
} from "@/manager/driver";

packages/actor-core/src/driver-test-suite/tests/actor-conn.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,10 @@ export function runActorConnTests(driverTestConfig: DriverTestConfig) {
211211
const conn1 = handle1.connect();
212212
const conn2 = handle2.connect();
213213

214+
// HACK: Call an action to wait for the connections to be established
215+
await conn1.getInitializers();
216+
await conn2.getInitializers();
217+
214218
// Get initializers to verify connection params were used
215219
const initializers = await conn1.getInitializers();
216220

packages/actor-core/src/manager/driver.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import type { ManagerInspector } from "@/inspector/manager";
33
import type { Env, Context as HonoContext } from "hono";
44

55
export interface ManagerDriver {
6-
getForId(input: GetForIdInput): Promise<GetActorOutput | undefined>;
7-
getWithKey(input: GetWithKeyInput): Promise<GetActorOutput | undefined>;
8-
createActor(input: CreateActorInput): Promise<CreateActorOutput>;
6+
getForId(input: GetForIdInput): Promise<ActorOutput | undefined>;
7+
getWithKey(input: GetWithKeyInput): Promise<ActorOutput | undefined>;
8+
getOrCreateWithKey(input: GetOrCreateWithKeyInput): Promise<ActorOutput>;
9+
createActor(input: CreateInput): Promise<ActorOutput>;
910

1011
inspector?: ManagerInspector;
1112
}
@@ -20,23 +21,23 @@ export interface GetWithKeyInput<E extends Env = any> {
2021
key: ActorKey;
2122
}
2223

23-
export interface GetActorOutput<E extends Env = any> {
24+
export interface GetOrCreateWithKeyInput<E extends Env = any> {
2425
c?: HonoContext<E>;
25-
actorId: string;
2626
name: string;
2727
key: ActorKey;
28-
meta?: unknown;
28+
region?: string;
2929
}
3030

31-
export interface CreateActorInput<E extends Env = any> {
31+
export interface CreateInput<E extends Env = any> {
3232
c?: HonoContext<E>;
3333
name: string;
3434
key: ActorKey;
3535
region?: string;
3636
}
3737

38-
export interface CreateActorOutput {
38+
export interface ActorOutput {
3939
actorId: string;
40+
name: string;
41+
key: ActorKey;
4042
meta?: unknown;
4143
}
42-

packages/actor-core/src/manager/router.ts

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -426,27 +426,16 @@ export async function queryActor(
426426
}
427427
actorOutput = existingActor;
428428
} else if ("getOrCreateForKey" in query) {
429-
const existingActor = await driver.getWithKey({
429+
const getOrCreateOutput = await driver.getOrCreateWithKey({
430430
c,
431431
name: query.getOrCreateForKey.name,
432432
key: query.getOrCreateForKey.key,
433+
region: query.getOrCreateForKey.region,
433434
});
434-
if (existingActor) {
435-
// Actor exists
436-
actorOutput = existingActor;
437-
} else {
438-
// Create if needed
439-
const createOutput = await driver.createActor({
440-
c,
441-
name: query.getOrCreateForKey.name,
442-
key: query.getOrCreateForKey.key,
443-
region: query.getOrCreateForKey.region,
444-
});
445-
actorOutput = {
446-
actorId: createOutput.actorId,
447-
meta: createOutput.meta,
448-
};
449-
}
435+
actorOutput = {
436+
actorId: getOrCreateOutput.actorId,
437+
meta: getOrCreateOutput.meta,
438+
};
450439
} else if ("create" in query) {
451440
const createOutput = await driver.createActor({
452441
c,
@@ -737,7 +726,7 @@ async function handleMessageRequest(
737726
);
738727
} else if ("custom" in handler.proxyMode) {
739728
logger().debug("using custom proxy mode for connection message");
740-
const url = new URL(`http://actor/connections/${connId}/message`);
729+
const url = new URL(`http://actor/connections/message`);
741730

742731
const proxyRequest = new Request(url, c.req.raw);
743732
proxyRequest.headers.set(HEADER_ENCODING, encoding);

packages/actor-core/src/test/driver/global-state.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
11
import type { ActorKey } from "@/mod";
22

33
/**
4-
* Class representing an actor's state
4+
* Interface representing an actor's state
55
*/
6-
export class ActorState {
7-
// Basic actor information
8-
initialized = true;
6+
export interface ActorState {
97
id: string;
108
name: string;
119
key: ActorKey;
12-
13-
// Persisted data
14-
persistedData: unknown = undefined;
15-
16-
constructor(id: string, name: string, key: ActorKey) {
17-
this.id = id;
18-
this.name = name;
19-
this.key = key;
20-
}
10+
persistedData: unknown;
2111
}
2212

2313
/**
@@ -45,7 +35,12 @@ export class TestGlobalState {
4535
createActor(actorId: string, name: string, key: ActorKey): void {
4636
// Create actor state if it doesn't exist
4737
if (!this.#actors.has(actorId)) {
48-
this.#actors.set(actorId, new ActorState(actorId, name, key));
38+
this.#actors.set(actorId, {
39+
id: actorId,
40+
name,
41+
key,
42+
persistedData: undefined
43+
});
4944
} else {
5045
throw new Error(`Actor already exists for ID: ${actorId}`);
5146
}

packages/actor-core/src/test/driver/manager.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import type {
2-
CreateActorInput,
3-
CreateActorOutput,
4-
GetActorOutput,
52
GetForIdInput,
63
GetWithKeyInput,
4+
GetOrCreateWithKeyInput,
75
ManagerDriver,
6+
CreateInput,
87
} from "@/driver-helpers/mod";
98
import { ActorAlreadyExists } from "@/actor/errors";
109
import type { TestGlobalState } from "./global-state";
1110
import * as crypto from "node:crypto";
1211
import { ManagerInspector } from "@/inspector/manager";
1312
import type { ActorCoreApp } from "@/app/mod";
13+
import { ActorOutput } from "@/manager/driver";
1414

1515
export class TestManagerDriver implements ManagerDriver {
1616
#state: TestGlobalState;
@@ -30,9 +30,7 @@ export class TestManagerDriver implements ManagerDriver {
3030
this.#state = state;
3131
}
3232

33-
async getForId({
34-
actorId,
35-
}: GetForIdInput): Promise<GetActorOutput | undefined> {
33+
async getForId({ actorId }: GetForIdInput): Promise<ActorOutput | undefined> {
3634
// Validate the actor exists
3735
const actor = this.#state.getActor(actorId);
3836
if (!actor) {
@@ -49,7 +47,7 @@ export class TestManagerDriver implements ManagerDriver {
4947
async getWithKey({
5048
name,
5149
key,
52-
}: GetWithKeyInput): Promise<GetActorOutput | undefined> {
50+
}: GetWithKeyInput): Promise<ActorOutput | undefined> {
5351
// NOTE: This is a slow implementation that checks each actor individually.
5452
// This can be optimized with an index in the future.
5553

@@ -115,10 +113,18 @@ export class TestManagerDriver implements ManagerDriver {
115113
return undefined;
116114
}
117115

118-
async createActor({
119-
name,
120-
key,
121-
}: CreateActorInput): Promise<CreateActorOutput> {
116+
async getOrCreateWithKey(
117+
input: GetOrCreateWithKeyInput,
118+
): Promise<ActorOutput> {
119+
const getOutput = await this.getWithKey(input);
120+
if (getOutput) {
121+
return getOutput;
122+
} else {
123+
return await this.createActor(input);
124+
}
125+
}
126+
127+
async createActor({ name, key }: CreateInput): Promise<ActorOutput> {
122128
// Check if actor with the same name and key already exists
123129
const existingActor = await this.getWithKey({ name, key });
124130
if (existingActor) {
@@ -132,6 +138,8 @@ export class TestManagerDriver implements ManagerDriver {
132138

133139
return {
134140
actorId,
141+
name,
142+
key,
135143
};
136144
}
137145
}

0 commit comments

Comments
 (0)