@langchain/langgraph 0.2.61 → 0.2.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/dist/constants.cjs +2 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -1
- package/dist/prebuilt/react_agent_executor.cjs +34 -13
- package/dist/prebuilt/react_agent_executor.d.ts +3 -0
- package/dist/prebuilt/react_agent_executor.js +34 -15
- package/dist/prebuilt/react_agent_executor.js.map +1 -1
- package/dist/prebuilt/tool_node.cjs +26 -4
- package/dist/prebuilt/tool_node.js +27 -5
- package/dist/prebuilt/tool_node.js.map +1 -1
- package/dist/pregel/debug.cjs +9 -7
- package/dist/pregel/debug.d.ts +10 -0
- package/dist/pregel/debug.js +2 -2
- package/dist/pregel/debug.js.map +1 -1
- package/dist/pregel/debug.test.cjs +189 -0
- package/dist/pregel/debug.test.d.ts +1 -0
- package/dist/pregel/debug.test.js +187 -0
- package/dist/pregel/debug.test.js.map +1 -0
- package/dist/pregel/index.cjs +12 -4
- package/dist/pregel/index.d.ts +3 -0
- package/dist/pregel/index.js +14 -6
- package/dist/pregel/index.js.map +1 -1
- package/dist/pregel/io.mapCommand.test.cjs +151 -0
- package/dist/pregel/io.mapCommand.test.d.ts +1 -0
- package/dist/pregel/io.mapCommand.test.js +149 -0
- package/dist/pregel/io.mapCommand.test.js.map +1 -0
- package/dist/pregel/messages.test.cjs +351 -0
- package/dist/pregel/messages.test.d.ts +1 -0
- package/dist/pregel/messages.test.js +349 -0
- package/dist/pregel/messages.test.js.map +1 -0
- package/dist/pregel/read.cjs +1 -1
- package/dist/pregel/read.js +1 -1
- package/dist/pregel/read.js.map +1 -1
- package/dist/pregel/read.test.cjs +194 -0
- package/dist/pregel/read.test.d.ts +1 -0
- package/dist/pregel/read.test.js +192 -0
- package/dist/pregel/read.test.js.map +1 -0
- package/dist/pregel/retry.cjs +5 -0
- package/dist/pregel/retry.d.ts +2 -0
- package/dist/pregel/retry.js +5 -0
- package/dist/pregel/retry.js.map +1 -1
- package/dist/pregel/runner.cjs +95 -27
- package/dist/pregel/runner.d.ts +14 -0
- package/dist/pregel/runner.js +97 -29
- package/dist/pregel/runner.js.map +1 -1
- package/dist/pregel/runner.test.cjs +66 -0
- package/dist/pregel/runner.test.d.ts +1 -0
- package/dist/pregel/runner.test.js +64 -0
- package/dist/pregel/runner.test.js.map +1 -0
- package/dist/pregel/stream.cjs +62 -1
- package/dist/pregel/stream.d.ts +23 -0
- package/dist/pregel/stream.js +60 -0
- package/dist/pregel/stream.js.map +1 -1
- package/dist/pregel/types.d.ts +19 -0
- package/dist/pregel/types.js.map +1 -1
- package/dist/pregel/utils/config.test.cjs +214 -0
- package/dist/pregel/utils/config.test.d.ts +1 -0
- package/dist/pregel/utils/config.test.js +212 -0
- package/dist/pregel/utils/config.test.js.map +1 -0
- package/dist/pregel/utils/index.cjs +26 -1
- package/dist/pregel/utils/index.d.ts +6 -0
- package/dist/pregel/utils/index.js +24 -0
- package/dist/pregel/utils/index.js.map +1 -1
- package/dist/pregel/utils/subgraph.test.cjs +83 -0
- package/dist/pregel/utils/subgraph.test.d.ts +1 -0
- package/dist/pregel/utils/subgraph.test.js +81 -0
- package/dist/pregel/utils/subgraph.test.js.map +1 -0
- package/dist/pregel/validate.test.cjs +220 -0
- package/dist/pregel/validate.test.d.ts +1 -0
- package/dist/pregel/validate.test.js +218 -0
- package/dist/pregel/validate.test.js.map +1 -0
- package/dist/pregel/write.test.cjs +181 -0
- package/dist/pregel/write.test.d.ts +1 -0
- package/dist/pregel/write.test.js +179 -0
- package/dist/pregel/write.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { describe, expect, it, jest } from "@jest/globals";
|
|
2
|
+
import { CONFIG_KEY_READ } from "../constants.js";
|
|
3
|
+
import { LastValue } from "../channels/last_value.js";
|
|
4
|
+
import { ChannelRead, PregelNode } from "./read.js";
|
|
5
|
+
import { ChannelWrite } from "./write.js";
|
|
6
|
+
describe("ChannelRead", () => {
|
|
7
|
+
it("should read a single channel value", async () => {
|
|
8
|
+
// Setup mock read function
|
|
9
|
+
const mockRead = jest
|
|
10
|
+
.fn()
|
|
11
|
+
.mockImplementation((channel) => {
|
|
12
|
+
if (channel === "test_channel") {
|
|
13
|
+
return "test_value";
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
});
|
|
17
|
+
const config = {
|
|
18
|
+
configurable: {
|
|
19
|
+
[CONFIG_KEY_READ]: mockRead,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
// Create channel read
|
|
23
|
+
const channelRead = new ChannelRead("test_channel");
|
|
24
|
+
// Run the channel read with our config
|
|
25
|
+
const result = await channelRead.invoke(null, config);
|
|
26
|
+
// Verify results
|
|
27
|
+
expect(result).toBe("test_value");
|
|
28
|
+
});
|
|
29
|
+
it("should read multiple channel values", async () => {
|
|
30
|
+
// Setup mock read function
|
|
31
|
+
const mockRead = jest
|
|
32
|
+
.fn()
|
|
33
|
+
.mockImplementation((channels) => {
|
|
34
|
+
if (Array.isArray(channels)) {
|
|
35
|
+
return {
|
|
36
|
+
channel1: "value1",
|
|
37
|
+
channel2: "value2",
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
});
|
|
42
|
+
const config = {
|
|
43
|
+
configurable: {
|
|
44
|
+
[CONFIG_KEY_READ]: mockRead,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
// Create channel read for multiple channels
|
|
48
|
+
const channelRead = new ChannelRead(["channel1", "channel2"]);
|
|
49
|
+
// Run the channel read with our config
|
|
50
|
+
const result = await channelRead.invoke(null, config);
|
|
51
|
+
// Verify results
|
|
52
|
+
expect(result).toEqual({
|
|
53
|
+
channel1: "value1",
|
|
54
|
+
channel2: "value2",
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
it("should apply a mapper function to the channel value", async () => {
|
|
58
|
+
// Setup mock read function
|
|
59
|
+
const mockRead = jest.fn().mockImplementation(() => "test_value");
|
|
60
|
+
const config = {
|
|
61
|
+
configurable: {
|
|
62
|
+
[CONFIG_KEY_READ]: mockRead,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
// Create mapper function
|
|
66
|
+
const mapper = (value) => `mapped_${value}`;
|
|
67
|
+
// Create channel read with mapper
|
|
68
|
+
const channelRead = new ChannelRead("test_channel", mapper);
|
|
69
|
+
// Run the channel read with our config
|
|
70
|
+
const result = await channelRead.invoke(null, config);
|
|
71
|
+
// Verify results
|
|
72
|
+
expect(result).toBe("mapped_test_value");
|
|
73
|
+
});
|
|
74
|
+
it("should throw an error if no read function is configured", async () => {
|
|
75
|
+
// Create channel read without configuring a read function
|
|
76
|
+
const channelRead = new ChannelRead("test_channel");
|
|
77
|
+
const config = {};
|
|
78
|
+
// Run the channel read with empty config
|
|
79
|
+
await expect(channelRead.invoke(null, config)).rejects.toThrow("not configured with a read function");
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe("PregelNode", () => {
|
|
83
|
+
it("should create a node that subscribes to channels", () => {
|
|
84
|
+
const node = new PregelNode({
|
|
85
|
+
channels: ["input", "context"],
|
|
86
|
+
triggers: ["input"],
|
|
87
|
+
});
|
|
88
|
+
expect(node.channels).toEqual(["input", "context"]);
|
|
89
|
+
expect(node.triggers).toEqual(["input"]);
|
|
90
|
+
});
|
|
91
|
+
it("should chain with ChannelWrite using pipe", () => {
|
|
92
|
+
const node = new PregelNode({
|
|
93
|
+
channels: ["input"],
|
|
94
|
+
triggers: ["input"],
|
|
95
|
+
});
|
|
96
|
+
const write = new ChannelWrite([
|
|
97
|
+
{ channel: "output", value: "test_output" },
|
|
98
|
+
]);
|
|
99
|
+
const pipeResult = node.pipe(write);
|
|
100
|
+
expect(pipeResult.writers).toHaveLength(1);
|
|
101
|
+
expect(pipeResult.writers[0]).toBe(write);
|
|
102
|
+
});
|
|
103
|
+
it("should combine multiple consecutive ChannelWrite instances", () => {
|
|
104
|
+
const node = new PregelNode({
|
|
105
|
+
channels: ["input"],
|
|
106
|
+
triggers: ["input"],
|
|
107
|
+
});
|
|
108
|
+
const write1 = new ChannelWrite([{ channel: "output1", value: "value1" }]);
|
|
109
|
+
const write2 = new ChannelWrite([{ channel: "output2", value: "value2" }]);
|
|
110
|
+
// Chain two writes
|
|
111
|
+
const pipeResult = node.pipe(write1).pipe(write2);
|
|
112
|
+
// Get optimized writers
|
|
113
|
+
const optimizedWriters = pipeResult.getWriters();
|
|
114
|
+
// Should be combined into a single ChannelWrite
|
|
115
|
+
expect(optimizedWriters).toHaveLength(1);
|
|
116
|
+
expect(optimizedWriters[0]).toBeInstanceOf(ChannelWrite);
|
|
117
|
+
expect(optimizedWriters[0].writes).toHaveLength(2);
|
|
118
|
+
});
|
|
119
|
+
it("should join additional channels", () => {
|
|
120
|
+
const node = new PregelNode({
|
|
121
|
+
channels: { input: "input", context: "context" },
|
|
122
|
+
triggers: ["input"],
|
|
123
|
+
});
|
|
124
|
+
const joinedNode = node.join(["history"]);
|
|
125
|
+
expect(joinedNode.channels).toEqual({
|
|
126
|
+
input: "input",
|
|
127
|
+
context: "context",
|
|
128
|
+
history: "history",
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
describe("Integrated Channel Read and Write", () => {
|
|
133
|
+
it("should perform direct channel operations", async () => {
|
|
134
|
+
// Use direct channel operations rather than depending on invoke
|
|
135
|
+
// Setup test environment with real channels
|
|
136
|
+
const channels = {
|
|
137
|
+
input: new LastValue(),
|
|
138
|
+
output: new LastValue(),
|
|
139
|
+
};
|
|
140
|
+
// Set initial value in input channel
|
|
141
|
+
channels.input.update(["test_input"]);
|
|
142
|
+
// Get value from input channel
|
|
143
|
+
const inputValue = channels.input.get();
|
|
144
|
+
expect(inputValue).toBe("test_input");
|
|
145
|
+
// Process value
|
|
146
|
+
const processedValue = `processed_${inputValue}`;
|
|
147
|
+
// Write to output channel
|
|
148
|
+
const updated = channels.output.update([processedValue]);
|
|
149
|
+
expect(updated).toBe(true);
|
|
150
|
+
// Read from output channel
|
|
151
|
+
const outputValue = channels.output.get();
|
|
152
|
+
expect(outputValue).toBe("processed_test_input");
|
|
153
|
+
});
|
|
154
|
+
it("should work with manual read and write operations", async () => {
|
|
155
|
+
// Setup test environment with real channels
|
|
156
|
+
const channels = {
|
|
157
|
+
input: new LastValue(),
|
|
158
|
+
output: new LastValue(),
|
|
159
|
+
};
|
|
160
|
+
// Initialize input channel with a value
|
|
161
|
+
channels.input.update(["test_input"]);
|
|
162
|
+
// Setup write tracking
|
|
163
|
+
let writtenValue = null;
|
|
164
|
+
// Manual read operation
|
|
165
|
+
const readFunc = (channel) => {
|
|
166
|
+
if (channel === "input") {
|
|
167
|
+
return channels.input.get();
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
};
|
|
171
|
+
// Manual write operation
|
|
172
|
+
const writeFunc = (values) => {
|
|
173
|
+
for (const [channel, value] of values) {
|
|
174
|
+
if (channel === "output") {
|
|
175
|
+
writtenValue = value;
|
|
176
|
+
channels.output.update([value]);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
// Read from input channel
|
|
181
|
+
const inputValue = readFunc("input");
|
|
182
|
+
expect(inputValue).toBe("test_input");
|
|
183
|
+
// Process the value
|
|
184
|
+
const processedValue = `processed_${inputValue}`;
|
|
185
|
+
// Write to output channel
|
|
186
|
+
writeFunc([["output", processedValue]]);
|
|
187
|
+
// Verify the write happened
|
|
188
|
+
expect(writtenValue).toBe("processed_test_input");
|
|
189
|
+
expect(channels.output.get()).toBe("processed_test_input");
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
//# sourceMappingURL=read.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.test.js","sourceRoot":"","sources":["../../src/pregel/read.test.ts"],"names":[],"mappings":"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"}
|
package/dist/pregel/retry.cjs
CHANGED
|
@@ -57,6 +57,10 @@ pregelTask, retryPolicy, configurable, signal) {
|
|
|
57
57
|
if (configurable) {
|
|
58
58
|
config = (0, index_js_1.patchConfigurable)(config, configurable);
|
|
59
59
|
}
|
|
60
|
+
config = {
|
|
61
|
+
...config,
|
|
62
|
+
signal,
|
|
63
|
+
};
|
|
60
64
|
// eslint-disable-next-line no-constant-condition
|
|
61
65
|
while (true) {
|
|
62
66
|
if (signal?.aborted) {
|
|
@@ -132,6 +136,7 @@ pregelTask, retryPolicy, configurable, signal) {
|
|
|
132
136
|
task: pregelTask,
|
|
133
137
|
result,
|
|
134
138
|
error: error,
|
|
139
|
+
signalAborted: signal?.aborted,
|
|
135
140
|
};
|
|
136
141
|
}
|
|
137
142
|
exports._runWithRetry = _runWithRetry;
|
package/dist/pregel/retry.d.ts
CHANGED
|
@@ -7,9 +7,11 @@ export declare const DEFAULT_MAX_RETRIES = 3;
|
|
|
7
7
|
export type SettledPregelTask = {
|
|
8
8
|
task: PregelExecutableTask<any, any>;
|
|
9
9
|
error: Error;
|
|
10
|
+
signalAborted?: boolean;
|
|
10
11
|
};
|
|
11
12
|
export declare function _runWithRetry<N extends PropertyKey, C extends PropertyKey>(pregelTask: PregelExecutableTask<N, C>, retryPolicy?: RetryPolicy, configurable?: Record<string, unknown>, signal?: AbortSignal): Promise<{
|
|
12
13
|
task: PregelExecutableTask<N, C>;
|
|
13
14
|
result: unknown;
|
|
14
15
|
error: Error | undefined;
|
|
16
|
+
signalAborted?: boolean;
|
|
15
17
|
}>;
|
package/dist/pregel/retry.js
CHANGED
|
@@ -54,6 +54,10 @@ pregelTask, retryPolicy, configurable, signal) {
|
|
|
54
54
|
if (configurable) {
|
|
55
55
|
config = patchConfigurable(config, configurable);
|
|
56
56
|
}
|
|
57
|
+
config = {
|
|
58
|
+
...config,
|
|
59
|
+
signal,
|
|
60
|
+
};
|
|
57
61
|
// eslint-disable-next-line no-constant-condition
|
|
58
62
|
while (true) {
|
|
59
63
|
if (signal?.aborted) {
|
|
@@ -129,6 +133,7 @@ pregelTask, retryPolicy, configurable, signal) {
|
|
|
129
133
|
task: pregelTask,
|
|
130
134
|
result,
|
|
131
135
|
error: error,
|
|
136
|
+
signalAborted: signal?.aborted,
|
|
132
137
|
};
|
|
133
138
|
}
|
|
134
139
|
//# sourceMappingURL=retry.js.map
|
package/dist/pregel/retry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/pregel/retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEhE,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAoB,MAAM,kBAAkB,CAAC;AAEvE,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAC;AAC5C,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAC3C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,MAAM,uBAAuB,GAAG;IAC9B,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG,EAAE,WAAW;CACjB,CAAC;AAEF,8DAA8D;AAC9D,MAAM,wBAAwB,GAAG,CAAC,KAAU,EAAE,EAAE;IAC9C,IACE,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC;QAClC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC;QACtC,KAAK,CAAC,IAAI,KAAK,YAAY,EAC3B;QACA,OAAO,KAAK,CAAC;KACd;IACD,8DAA8D;IAC9D,IAAK,KAAa,EAAE,IAAI,KAAK,cAAc,EAAE;QAC3C,OAAO,KAAK,CAAC;KACd;IACD,MAAM,MAAM;IACV,8DAA8D;IAC7D,KAAa,EAAE,QAAQ,EAAE,MAAM,IAAK,KAAa,EAAE,MAAM,CAAC;IAC7D,IAAI,MAAM,IAAI,uBAAuB,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE;QACvD,OAAO,KAAK,CAAC;KACd;IACD,8DAA8D;IAC9D,IAAK,KAAa,EAAE,KAAK,EAAE,IAAI,KAAK,oBAAoB,EAAE;QACxD,OAAO,KAAK,CAAC;KACd;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/pregel/retry.ts"],"names":[],"mappings":"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"}
|
package/dist/pregel/runner.cjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PregelRunner = void 0;
|
|
4
4
|
const types_js_1 = require("./types.cjs");
|
|
5
|
+
const index_js_1 = require("./utils/index.cjs");
|
|
5
6
|
const constants_js_1 = require("../constants.cjs");
|
|
6
7
|
const errors_js_1 = require("../errors.cjs");
|
|
7
8
|
const retry_js_1 = require("./retry.cjs");
|
|
@@ -36,18 +37,23 @@ class PregelRunner {
|
|
|
36
37
|
* @param options - Options for the execution.
|
|
37
38
|
*/
|
|
38
39
|
async tick(options = {}) {
|
|
39
|
-
const { timeout,
|
|
40
|
+
const { timeout, retryPolicy, onStepWrite, maxConcurrency } = options;
|
|
40
41
|
const nodeErrors = new Set();
|
|
41
42
|
let graphBubbleUp;
|
|
43
|
+
const exceptionSignalController = new AbortController();
|
|
42
44
|
// Start task execution
|
|
43
45
|
const pendingTasks = Object.values(this.loop.tasks).filter((t) => t.writes.length === 0);
|
|
46
|
+
const currentSignals = this._initializeAbortSignals({
|
|
47
|
+
exceptionSignalController,
|
|
48
|
+
timeout,
|
|
49
|
+
signal: options.signal,
|
|
50
|
+
});
|
|
44
51
|
const taskStream = this._executeTasksWithRetry(pendingTasks, {
|
|
45
|
-
|
|
46
|
-
signal,
|
|
52
|
+
signals: currentSignals,
|
|
47
53
|
retryPolicy,
|
|
48
54
|
maxConcurrency,
|
|
49
55
|
});
|
|
50
|
-
for await (const { task, error } of taskStream) {
|
|
56
|
+
for await (const { task, error, signalAborted } of taskStream) {
|
|
51
57
|
this._commit(task, error);
|
|
52
58
|
if ((0, errors_js_1.isGraphInterrupt)(error)) {
|
|
53
59
|
graphBubbleUp = error;
|
|
@@ -55,7 +61,22 @@ class PregelRunner {
|
|
|
55
61
|
else if ((0, errors_js_1.isGraphBubbleUp)(error) && !(0, errors_js_1.isGraphInterrupt)(graphBubbleUp)) {
|
|
56
62
|
graphBubbleUp = error;
|
|
57
63
|
}
|
|
58
|
-
else if (error) {
|
|
64
|
+
else if (error && (nodeErrors.size === 0 || !signalAborted)) {
|
|
65
|
+
/*
|
|
66
|
+
* The goal here is to capture the exception that causes the graph to terminate early. In
|
|
67
|
+
* theory it's possible for multiple nodes to throw, so this also handles the edge case of
|
|
68
|
+
* capturing concurrent exceptions thrown before the node saw an abort. This is checked via
|
|
69
|
+
* the signalAborted flag, which records the state of the abort signal at the time the node
|
|
70
|
+
* execution finished.
|
|
71
|
+
*
|
|
72
|
+
* There is a case however where one node throws some error causing us to trigger an abort,
|
|
73
|
+
* which then causes other concurrently executing nodes to throw their own AbortErrors. In
|
|
74
|
+
* this case we don't care about reporting the abort errors thrown by the other nodes,
|
|
75
|
+
* because they don't tell the user anything about what caused the graph execution to
|
|
76
|
+
* terminate early, so we ignore them (and any other errors that occur after the node sees
|
|
77
|
+
* an abort signal).
|
|
78
|
+
*/
|
|
79
|
+
exceptionSignalController.abort();
|
|
59
80
|
nodeErrors.add(error);
|
|
60
81
|
}
|
|
61
82
|
}
|
|
@@ -75,14 +96,60 @@ class PregelRunner {
|
|
|
75
96
|
throw graphBubbleUp;
|
|
76
97
|
}
|
|
77
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Initializes the current AbortSignals for the PregelRunner, handling the various ways that
|
|
101
|
+
* AbortSignals must be chained together so that the PregelLoop can be interrupted if necessary
|
|
102
|
+
* while still allowing nodes to gracefully exit.
|
|
103
|
+
*
|
|
104
|
+
* This method must only be called once per PregelRunner#tick. It has the side effect of updating
|
|
105
|
+
* the PregelLoop#config with the new AbortSignals so they may be propagated correctly to future
|
|
106
|
+
* ticks and subgraph calls.
|
|
107
|
+
*
|
|
108
|
+
* @param options - Options for the initialization.
|
|
109
|
+
* @returns The current abort signals.
|
|
110
|
+
* @internal
|
|
111
|
+
*/
|
|
112
|
+
_initializeAbortSignals({ exceptionSignalController, timeout, signal, }) {
|
|
113
|
+
const previousSignals = this.loop.config.configurable?.[constants_js_1.CONFIG_KEY_ABORT_SIGNALS] ?? {};
|
|
114
|
+
// This is true when a node calls a subgraph and, rather than forwarding its own AbortSignal,
|
|
115
|
+
// it creates a new AbortSignal and passes that along instead.
|
|
116
|
+
const subgraphCalledWithSignalCreatedByNode = signal &&
|
|
117
|
+
previousSignals.composedAbortSignal &&
|
|
118
|
+
signal !== previousSignals.composedAbortSignal;
|
|
119
|
+
const externalAbortSignal = subgraphCalledWithSignalCreatedByNode
|
|
120
|
+
? // Chain the signals here to make sure that the subgraph receives the external abort signal in
|
|
121
|
+
// addition to the signal created by the node.
|
|
122
|
+
(0, index_js_1.combineAbortSignals)(previousSignals.externalAbortSignal, signal)
|
|
123
|
+
: // Otherwise, just keep using the external abort signal, or initialize it if it hasn't been
|
|
124
|
+
// assigned yet
|
|
125
|
+
previousSignals.externalAbortSignal ?? signal;
|
|
126
|
+
const errorAbortSignal = previousSignals.errorAbortSignal
|
|
127
|
+
? // Chaining here rather than always using a fresh one handles the case where a subgraph is
|
|
128
|
+
// called in a parallel branch to some other node in the parent graph.
|
|
129
|
+
(0, index_js_1.combineAbortSignals)(previousSignals.errorAbortSignal, exceptionSignalController.signal)
|
|
130
|
+
: exceptionSignalController.signal;
|
|
131
|
+
const timeoutAbortSignal = timeout
|
|
132
|
+
? AbortSignal.timeout(timeout)
|
|
133
|
+
: undefined;
|
|
134
|
+
const composedAbortSignal = (0, index_js_1.combineAbortSignals)(...(externalAbortSignal ? [externalAbortSignal] : []), ...(timeoutAbortSignal ? [timeoutAbortSignal] : []), errorAbortSignal);
|
|
135
|
+
const currentSignals = {
|
|
136
|
+
externalAbortSignal,
|
|
137
|
+
errorAbortSignal,
|
|
138
|
+
timeoutAbortSignal,
|
|
139
|
+
composedAbortSignal,
|
|
140
|
+
};
|
|
141
|
+
this.loop.config = (0, index_js_1.patchConfigurable)(this.loop.config, {
|
|
142
|
+
[constants_js_1.CONFIG_KEY_ABORT_SIGNALS]: currentSignals,
|
|
143
|
+
});
|
|
144
|
+
return currentSignals;
|
|
145
|
+
}
|
|
78
146
|
/**
|
|
79
147
|
* Concurrently executes tasks with the requested retry policy, yielding a {@link SettledPregelTask} for each task as it completes.
|
|
80
148
|
* @param tasks - The tasks to execute.
|
|
81
149
|
* @param options - Options for the execution.
|
|
82
150
|
*/
|
|
83
151
|
async *_executeTasksWithRetry(tasks, options) {
|
|
84
|
-
const {
|
|
85
|
-
let signal = options?.signal;
|
|
152
|
+
const { retryPolicy, maxConcurrency, signals } = options ?? {};
|
|
86
153
|
const promiseAddedSymbol = Symbol.for("promiseAdded");
|
|
87
154
|
let addedPromiseSignal;
|
|
88
155
|
let addedPromiseWait;
|
|
@@ -196,29 +263,26 @@ class PregelRunner {
|
|
|
196
263
|
}
|
|
197
264
|
return Promise.resolve();
|
|
198
265
|
}
|
|
199
|
-
if (
|
|
200
|
-
if ("any" in AbortSignal) {
|
|
201
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
202
|
-
signal = AbortSignal.any([
|
|
203
|
-
signal,
|
|
204
|
-
AbortSignal.timeout(stepTimeout),
|
|
205
|
-
]);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
else if (stepTimeout) {
|
|
209
|
-
signal = AbortSignal.timeout(stepTimeout);
|
|
210
|
-
}
|
|
211
|
-
if (signal?.aborted) {
|
|
266
|
+
if (signals?.composedAbortSignal?.aborted) {
|
|
212
267
|
// note: don't use throwIfAborted here because it throws a DOMException,
|
|
213
268
|
// which isn't consistent with how we throw on abort below.
|
|
214
269
|
throw new Error("Abort");
|
|
215
270
|
}
|
|
216
271
|
let startedTasksCount = 0;
|
|
217
272
|
let listener;
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
273
|
+
const timeoutOrCancelSignal = signals?.externalAbortSignal || signals?.timeoutAbortSignal
|
|
274
|
+
? (0, index_js_1.combineAbortSignals)(...(signals.externalAbortSignal
|
|
275
|
+
? [signals.externalAbortSignal]
|
|
276
|
+
: []), ...(signals.timeoutAbortSignal ? [signals.timeoutAbortSignal] : []))
|
|
277
|
+
: undefined;
|
|
278
|
+
const abortPromise = timeoutOrCancelSignal
|
|
279
|
+
? new Promise((_resolve, reject) => {
|
|
280
|
+
listener = () => reject(new Error("Abort"));
|
|
281
|
+
timeoutOrCancelSignal.addEventListener("abort", listener, {
|
|
282
|
+
once: true,
|
|
283
|
+
});
|
|
284
|
+
})
|
|
285
|
+
: undefined;
|
|
222
286
|
while ((startedTasksCount === 0 || Object.keys(executingTasksMap).length > 0) &&
|
|
223
287
|
tasks.length) {
|
|
224
288
|
for (; Object.values(executingTasksMap).length <
|
|
@@ -227,13 +291,17 @@ class PregelRunner {
|
|
|
227
291
|
executingTasksMap[task.id] = (0, retry_js_1._runWithRetry)(task, retryPolicy, {
|
|
228
292
|
[constants_js_1.CONFIG_KEY_SEND]: writer?.bind(null, this, task),
|
|
229
293
|
[constants_js_1.CONFIG_KEY_CALL]: call?.bind(null, this, task),
|
|
230
|
-
}).catch((error) => {
|
|
231
|
-
return {
|
|
294
|
+
}, signals?.composedAbortSignal).catch((error) => {
|
|
295
|
+
return {
|
|
296
|
+
task,
|
|
297
|
+
error,
|
|
298
|
+
signalAborted: signals?.composedAbortSignal?.aborted,
|
|
299
|
+
};
|
|
232
300
|
});
|
|
233
301
|
}
|
|
234
302
|
const settledTask = await Promise.race([
|
|
235
303
|
...Object.values(executingTasksMap),
|
|
236
|
-
|
|
304
|
+
...(abortPromise ? [abortPromise] : []),
|
|
237
305
|
addedPromiseWait,
|
|
238
306
|
]);
|
|
239
307
|
if (settledTask === promiseAddedSymbol) {
|
package/dist/pregel/runner.d.ts
CHANGED
|
@@ -47,6 +47,20 @@ export declare class PregelRunner {
|
|
|
47
47
|
* @param options - Options for the execution.
|
|
48
48
|
*/
|
|
49
49
|
tick(options?: TickOptions): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Initializes the current AbortSignals for the PregelRunner, handling the various ways that
|
|
52
|
+
* AbortSignals must be chained together so that the PregelLoop can be interrupted if necessary
|
|
53
|
+
* while still allowing nodes to gracefully exit.
|
|
54
|
+
*
|
|
55
|
+
* This method must only be called once per PregelRunner#tick. It has the side effect of updating
|
|
56
|
+
* the PregelLoop#config with the new AbortSignals so they may be propagated correctly to future
|
|
57
|
+
* ticks and subgraph calls.
|
|
58
|
+
*
|
|
59
|
+
* @param options - Options for the initialization.
|
|
60
|
+
* @returns The current abort signals.
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
private _initializeAbortSignals;
|
|
50
64
|
/**
|
|
51
65
|
* Concurrently executes tasks with the requested retry policy, yielding a {@link SettledPregelTask} for each task as it completes.
|
|
52
66
|
* @param tasks - The tasks to execute.
|