-
Notifications
You must be signed in to change notification settings - Fork 235
Expand file tree
/
Copy pathmanager.ts
More file actions
110 lines (94 loc) · 2.59 KB
/
Copy pathmanager.ts
File metadata and controls
110 lines (94 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import type {
CreateInput,
GetForIdInput,
GetWithKeyInput,
GetOrCreateWithKeyInput,
WorkerOutput,
ManagerDriver,
} from "rivetkit/driver-helpers";
import { WorkerAlreadyExists } from "rivetkit/errors";
import type { MemoryGlobalState } from "./global-state";
import * as crypto from "node:crypto";
import { ManagerInspector } from "rivetkit/inspector";
import type { Registry } from "rivetkit";
export class MemoryManagerDriver implements ManagerDriver {
#state: MemoryGlobalState;
/**
* @internal
*/
inspector: ManagerInspector = new ManagerInspector(this, {
getAllWorkers: () => this.#state.getAllWorkers(),
getAllTypesOfWorkers: () => Object.keys(this.registry.config.workers),
});
constructor(
private readonly registry: Registry<any>,
state: MemoryGlobalState,
) {
this.#state = state;
}
async getForId({
workerId,
}: GetForIdInput): Promise<WorkerOutput | undefined> {
// Validate the worker exists
const worker = this.#state.getWorker(workerId);
if (!worker) {
return undefined;
}
return {
workerId: worker.id,
name: worker.name,
key: worker.key,
};
}
async getWithKey({
name,
key,
}: GetWithKeyInput): Promise<WorkerOutput | undefined> {
// NOTE: This is a slow implementation that checks each worker individually.
// This can be optimized with an index in the future.
// Search through all workers to find a match
const worker = this.#state.findWorker((worker) => {
if (worker.name !== name) return false;
// If worker doesn't have a key, it's not a match
if (!worker.key || worker.key.length !== key.length) {
return false;
}
// Check if all elements in key are in worker.key
for (let i = 0; i < key.length; i++) {
if (key[i] !== worker.key[i]) {
return false;
}
}
return true;
});
if (worker) {
return {
workerId: worker.id,
name,
key: worker.key,
};
}
return undefined;
}
async getOrCreateWithKey(
input: GetOrCreateWithKeyInput,
): Promise<WorkerOutput> {
const getOutput = await this.getWithKey(input);
if (getOutput) {
return getOutput;
} else {
return await this.createWorker(input);
}
}
async createWorker({ name, key, input }: CreateInput): Promise<WorkerOutput> {
// Check if worker with the same name and key already exists
const existingWorker = await this.getWithKey({ name, key });
if (existingWorker) {
throw new WorkerAlreadyExists(name, key);
}
const workerId = crypto.randomUUID();
this.#state.createWorker(workerId, name, key, input);
this.inspector.onWorkersChange(this.#state.getAllWorkers());
return { workerId, name, key };
}
}