@trigger.dev/core 4.0.7 → 4.1.0
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/dist/commonjs/v3/apiClient/index.d.ts +24 -4
- package/dist/commonjs/v3/apiClient/index.js +48 -4
- package/dist/commonjs/v3/apiClient/index.js.map +1 -1
- package/dist/commonjs/v3/apiClient/runStream.d.ts +28 -14
- package/dist/commonjs/v3/apiClient/runStream.js +175 -58
- package/dist/commonjs/v3/apiClient/runStream.js.map +1 -1
- package/dist/commonjs/v3/apiClientManager/index.d.ts +1 -1
- package/dist/commonjs/v3/apiClientManager/index.js +11 -4
- package/dist/commonjs/v3/apiClientManager/index.js.map +1 -1
- package/dist/commonjs/v3/apiClientManager/types.d.ts +2 -1
- package/dist/commonjs/v3/index.d.ts +1 -0
- package/dist/commonjs/v3/index.js +1 -0
- package/dist/commonjs/v3/index.js.map +1 -1
- package/dist/commonjs/v3/lifecycle-hooks-api.d.ts +1 -1
- package/dist/commonjs/v3/lifecycleHooks/index.d.ts +5 -1
- package/dist/commonjs/v3/lifecycleHooks/index.js +12 -0
- package/dist/commonjs/v3/lifecycleHooks/index.js.map +1 -1
- package/dist/commonjs/v3/lifecycleHooks/manager.d.ts +11 -1
- package/dist/commonjs/v3/lifecycleHooks/manager.js +36 -0
- package/dist/commonjs/v3/lifecycleHooks/manager.js.map +1 -1
- package/dist/commonjs/v3/lifecycleHooks/types.d.ts +12 -0
- package/dist/commonjs/v3/realtime-streams-api.d.ts +3 -0
- package/dist/commonjs/v3/realtime-streams-api.js +23 -0
- package/dist/commonjs/v3/realtime-streams-api.js.map +1 -0
- package/dist/commonjs/v3/realtimeStreams/index.d.ts +10 -0
- package/dist/commonjs/v3/realtimeStreams/index.js +31 -0
- package/dist/commonjs/v3/realtimeStreams/index.js.map +1 -0
- package/dist/commonjs/v3/realtimeStreams/manager.d.ts +14 -0
- package/dist/commonjs/v3/realtimeStreams/manager.js +128 -0
- package/dist/commonjs/v3/realtimeStreams/manager.js.map +1 -0
- package/dist/commonjs/v3/realtimeStreams/noopManager.d.ts +5 -0
- package/dist/commonjs/v3/realtimeStreams/noopManager.js +17 -0
- package/dist/commonjs/v3/realtimeStreams/noopManager.js.map +1 -0
- package/dist/commonjs/v3/realtimeStreams/streamInstance.d.ts +23 -0
- package/dist/commonjs/v3/realtimeStreams/streamInstance.js +106 -0
- package/dist/commonjs/v3/realtimeStreams/streamInstance.js.map +1 -0
- package/dist/commonjs/v3/realtimeStreams/streamsWriterV1.d.ts +49 -0
- package/dist/commonjs/v3/realtimeStreams/streamsWriterV1.js +382 -0
- package/dist/commonjs/v3/realtimeStreams/streamsWriterV1.js.map +1 -0
- package/dist/commonjs/v3/realtimeStreams/streamsWriterV2.d.ts +60 -0
- package/dist/commonjs/v3/realtimeStreams/streamsWriterV2.js +179 -0
- package/dist/commonjs/v3/realtimeStreams/streamsWriterV2.js.map +1 -0
- package/dist/commonjs/v3/realtimeStreams/types.d.ts +119 -0
- package/dist/commonjs/v3/realtimeStreams/types.js +3 -0
- package/dist/commonjs/v3/realtimeStreams/types.js.map +1 -0
- package/dist/commonjs/v3/runEngineWorker/supervisor/http.d.ts +1 -0
- package/dist/commonjs/v3/runEngineWorker/supervisor/schemas.d.ts +7 -0
- package/dist/commonjs/v3/runEngineWorker/workload/http.d.ts +1 -0
- package/dist/commonjs/v3/runEngineWorker/workload/schemas.d.ts +7 -0
- package/dist/commonjs/v3/runMetadata/manager.d.ts +3 -8
- package/dist/commonjs/v3/runMetadata/manager.js +14 -79
- package/dist/commonjs/v3/runMetadata/manager.js.map +1 -1
- package/dist/commonjs/v3/schemas/api.d.ts +22 -0
- package/dist/commonjs/v3/schemas/api.js +9 -1
- package/dist/commonjs/v3/schemas/api.js.map +1 -1
- package/dist/commonjs/v3/schemas/common.d.ts +5 -0
- package/dist/commonjs/v3/schemas/common.js +1 -0
- package/dist/commonjs/v3/schemas/common.js.map +1 -1
- package/dist/commonjs/v3/schemas/messages.d.ts +35 -0
- package/dist/commonjs/v3/schemas/runEngine.d.ts +7 -0
- package/dist/commonjs/v3/schemas/schemas.d.ts +7 -0
- package/dist/commonjs/v3/semanticInternalAttributes.d.ts +1 -0
- package/dist/commonjs/v3/semanticInternalAttributes.js +1 -0
- package/dist/commonjs/v3/semanticInternalAttributes.js.map +1 -1
- package/dist/commonjs/v3/streams/asyncIterableStream.d.ts +2 -0
- package/dist/commonjs/v3/streams/asyncIterableStream.js +47 -0
- package/dist/commonjs/v3/streams/asyncIterableStream.js.map +1 -1
- package/dist/commonjs/v3/types/tasks.d.ts +17 -2
- package/dist/commonjs/v3/types/tasks.js.map +1 -1
- package/dist/commonjs/v3/utils/globals.d.ts +2 -0
- package/dist/commonjs/v3/utils/globals.js.map +1 -1
- package/dist/commonjs/v3/waitUntil/index.d.ts +1 -1
- package/dist/commonjs/v3/waitUntil/index.js +3 -3
- package/dist/commonjs/v3/waitUntil/index.js.map +1 -1
- package/dist/commonjs/v3/waitUntil/manager.d.ts +3 -1
- package/dist/commonjs/v3/waitUntil/manager.js +7 -3
- package/dist/commonjs/v3/waitUntil/manager.js.map +1 -1
- package/dist/commonjs/v3/waitUntil/types.d.ts +2 -2
- package/dist/commonjs/v3/workers/index.d.ts +1 -0
- package/dist/commonjs/v3/workers/index.js +3 -1
- package/dist/commonjs/v3/workers/index.js.map +1 -1
- package/dist/commonjs/v3/workers/taskExecutor.js +50 -25
- package/dist/commonjs/v3/workers/taskExecutor.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/esm/v3/apiClient/index.d.ts +24 -4
- package/dist/esm/v3/apiClient/index.js +49 -6
- package/dist/esm/v3/apiClient/index.js.map +1 -1
- package/dist/esm/v3/apiClient/runStream.d.ts +28 -14
- package/dist/esm/v3/apiClient/runStream.js +176 -58
- package/dist/esm/v3/apiClient/runStream.js.map +1 -1
- package/dist/esm/v3/apiClientManager/index.d.ts +1 -1
- package/dist/esm/v3/apiClientManager/index.js +11 -4
- package/dist/esm/v3/apiClientManager/index.js.map +1 -1
- package/dist/esm/v3/apiClientManager/types.d.ts +2 -1
- package/dist/esm/v3/index.d.ts +1 -0
- package/dist/esm/v3/index.js +1 -0
- package/dist/esm/v3/index.js.map +1 -1
- package/dist/esm/v3/lifecycle-hooks-api.d.ts +1 -1
- package/dist/esm/v3/lifecycleHooks/index.d.ts +5 -1
- package/dist/esm/v3/lifecycleHooks/index.js +12 -0
- package/dist/esm/v3/lifecycleHooks/index.js.map +1 -1
- package/dist/esm/v3/lifecycleHooks/manager.d.ts +11 -1
- package/dist/esm/v3/lifecycleHooks/manager.js +36 -0
- package/dist/esm/v3/lifecycleHooks/manager.js.map +1 -1
- package/dist/esm/v3/lifecycleHooks/types.d.ts +12 -0
- package/dist/esm/v3/realtime-streams-api.d.ts +3 -0
- package/dist/esm/v3/realtime-streams-api.js +6 -0
- package/dist/esm/v3/realtime-streams-api.js.map +1 -0
- package/dist/esm/v3/realtimeStreams/index.d.ts +10 -0
- package/dist/esm/v3/realtimeStreams/index.js +27 -0
- package/dist/esm/v3/realtimeStreams/index.js.map +1 -0
- package/dist/esm/v3/realtimeStreams/manager.d.ts +14 -0
- package/dist/esm/v3/realtimeStreams/manager.js +124 -0
- package/dist/esm/v3/realtimeStreams/manager.js.map +1 -0
- package/dist/esm/v3/realtimeStreams/noopManager.d.ts +5 -0
- package/dist/esm/v3/realtimeStreams/noopManager.js +13 -0
- package/dist/esm/v3/realtimeStreams/noopManager.js.map +1 -0
- package/dist/esm/v3/realtimeStreams/streamInstance.d.ts +23 -0
- package/dist/esm/v3/realtimeStreams/streamInstance.js +102 -0
- package/dist/esm/v3/realtimeStreams/streamInstance.js.map +1 -0
- package/dist/esm/v3/realtimeStreams/streamsWriterV1.d.ts +49 -0
- package/dist/esm/v3/realtimeStreams/streamsWriterV1.js +378 -0
- package/dist/esm/v3/realtimeStreams/streamsWriterV1.js.map +1 -0
- package/dist/esm/v3/realtimeStreams/streamsWriterV2.d.ts +60 -0
- package/dist/esm/v3/realtimeStreams/streamsWriterV2.js +175 -0
- package/dist/esm/v3/realtimeStreams/streamsWriterV2.js.map +1 -0
- package/dist/esm/v3/realtimeStreams/types.d.ts +119 -0
- package/dist/esm/v3/realtimeStreams/types.js +2 -0
- package/dist/esm/v3/realtimeStreams/types.js.map +1 -0
- package/dist/esm/v3/runEngineWorker/supervisor/http.d.ts +1 -0
- package/dist/esm/v3/runEngineWorker/supervisor/schemas.d.ts +7 -0
- package/dist/esm/v3/runEngineWorker/workload/http.d.ts +1 -0
- package/dist/esm/v3/runEngineWorker/workload/schemas.d.ts +7 -0
- package/dist/esm/v3/runMetadata/manager.d.ts +3 -8
- package/dist/esm/v3/runMetadata/manager.js +14 -79
- package/dist/esm/v3/runMetadata/manager.js.map +1 -1
- package/dist/esm/v3/schemas/api.d.ts +22 -0
- package/dist/esm/v3/schemas/api.js +8 -0
- package/dist/esm/v3/schemas/api.js.map +1 -1
- package/dist/esm/v3/schemas/common.d.ts +5 -0
- package/dist/esm/v3/schemas/common.js +1 -0
- package/dist/esm/v3/schemas/common.js.map +1 -1
- package/dist/esm/v3/schemas/messages.d.ts +35 -0
- package/dist/esm/v3/schemas/runEngine.d.ts +7 -0
- package/dist/esm/v3/schemas/schemas.d.ts +7 -0
- package/dist/esm/v3/semanticInternalAttributes.d.ts +1 -0
- package/dist/esm/v3/semanticInternalAttributes.js +1 -0
- package/dist/esm/v3/semanticInternalAttributes.js.map +1 -1
- package/dist/esm/v3/streams/asyncIterableStream.d.ts +2 -0
- package/dist/esm/v3/streams/asyncIterableStream.js +45 -0
- package/dist/esm/v3/streams/asyncIterableStream.js.map +1 -1
- package/dist/esm/v3/types/tasks.d.ts +17 -2
- package/dist/esm/v3/types/tasks.js.map +1 -1
- package/dist/esm/v3/utils/globals.d.ts +2 -0
- package/dist/esm/v3/utils/globals.js.map +1 -1
- package/dist/esm/v3/waitUntil/index.d.ts +1 -1
- package/dist/esm/v3/waitUntil/index.js +3 -3
- package/dist/esm/v3/waitUntil/index.js.map +1 -1
- package/dist/esm/v3/waitUntil/manager.d.ts +3 -1
- package/dist/esm/v3/waitUntil/manager.js +7 -3
- package/dist/esm/v3/waitUntil/manager.js.map +1 -1
- package/dist/esm/v3/waitUntil/types.d.ts +2 -2
- package/dist/esm/v3/workers/index.d.ts +1 -0
- package/dist/esm/v3/workers/index.js +1 -0
- package/dist/esm/v3/workers/index.js.map +1 -1
- package/dist/esm/v3/workers/taskExecutor.js +50 -25
- package/dist/esm/v3/workers/taskExecutor.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +2 -1
- package/dist/commonjs/v3/runMetadata/metadataStream.d.ts +0 -28
- package/dist/commonjs/v3/runMetadata/metadataStream.js +0 -155
- package/dist/commonjs/v3/runMetadata/metadataStream.js.map +0 -1
- package/dist/esm/v3/runMetadata/metadataStream.d.ts +0 -28
- package/dist/esm/v3/runMetadata/metadataStream.js +0 -151
- package/dist/esm/v3/runMetadata/metadataStream.js.map +0 -1
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import { request as httpsRequest } from "node:https";
|
|
2
|
+
import { request as httpRequest } from "node:http";
|
|
3
|
+
import { URL } from "node:url";
|
|
4
|
+
import { randomBytes } from "node:crypto";
|
|
5
|
+
export class StreamsWriterV1 {
|
|
6
|
+
options;
|
|
7
|
+
controller = new AbortController();
|
|
8
|
+
serverStream;
|
|
9
|
+
consumerStream;
|
|
10
|
+
streamPromise;
|
|
11
|
+
retryCount = 0;
|
|
12
|
+
maxRetries;
|
|
13
|
+
currentChunkIndex = 0;
|
|
14
|
+
baseDelayMs = 1000; // 1 second base delay
|
|
15
|
+
maxDelayMs = 30000; // 30 seconds max delay
|
|
16
|
+
maxBufferSize;
|
|
17
|
+
clientId;
|
|
18
|
+
ringBuffer = []; // Ring buffer for recent chunks
|
|
19
|
+
bufferStartIndex = 0; // Index of the oldest chunk in buffer
|
|
20
|
+
highestBufferedIndex = -1; // Highest chunk index that's been buffered
|
|
21
|
+
streamReader = null;
|
|
22
|
+
bufferReaderTask = null;
|
|
23
|
+
streamComplete = false;
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.options = options;
|
|
26
|
+
const [serverStream, consumerStream] = this.options.source.tee();
|
|
27
|
+
this.serverStream = serverStream;
|
|
28
|
+
this.consumerStream = consumerStream;
|
|
29
|
+
this.maxRetries = options.maxRetries ?? 10;
|
|
30
|
+
this.maxBufferSize = options.maxBufferSize ?? 10000; // Default 10000 chunks
|
|
31
|
+
this.clientId = options.clientId || this.generateClientId();
|
|
32
|
+
// Start background task to continuously read from stream into ring buffer
|
|
33
|
+
this.startBuffering();
|
|
34
|
+
this.streamPromise = this.initializeServerStream();
|
|
35
|
+
}
|
|
36
|
+
generateClientId() {
|
|
37
|
+
return randomBytes(4).toString("hex");
|
|
38
|
+
}
|
|
39
|
+
startBuffering() {
|
|
40
|
+
this.streamReader = this.serverStream.getReader();
|
|
41
|
+
this.bufferReaderTask = (async () => {
|
|
42
|
+
try {
|
|
43
|
+
let chunkIndex = 0;
|
|
44
|
+
while (true) {
|
|
45
|
+
const { done, value } = await this.streamReader.read();
|
|
46
|
+
if (done) {
|
|
47
|
+
this.streamComplete = true;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
// Add to ring buffer
|
|
51
|
+
this.addToRingBuffer(chunkIndex, value);
|
|
52
|
+
this.highestBufferedIndex = chunkIndex;
|
|
53
|
+
chunkIndex++;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
})();
|
|
60
|
+
}
|
|
61
|
+
async makeRequest(startFromChunk = 0) {
|
|
62
|
+
return new Promise((resolve, reject) => {
|
|
63
|
+
const url = new URL(this.buildUrl());
|
|
64
|
+
const timeout = 15 * 60 * 1000; // 15 minutes
|
|
65
|
+
const requestFn = url.protocol === "https:" ? httpsRequest : httpRequest;
|
|
66
|
+
const req = requestFn({
|
|
67
|
+
method: "POST",
|
|
68
|
+
hostname: url.hostname,
|
|
69
|
+
port: url.port || (url.protocol === "https:" ? 443 : 80),
|
|
70
|
+
path: url.pathname + url.search,
|
|
71
|
+
headers: {
|
|
72
|
+
...this.options.headers,
|
|
73
|
+
"Content-Type": "application/json",
|
|
74
|
+
"X-Client-Id": this.clientId,
|
|
75
|
+
"X-Resume-From-Chunk": startFromChunk.toString(),
|
|
76
|
+
"X-Stream-Version": this.options.version ?? "v1",
|
|
77
|
+
},
|
|
78
|
+
timeout,
|
|
79
|
+
});
|
|
80
|
+
req.on("error", async (error) => {
|
|
81
|
+
const errorCode = "code" in error ? error.code : undefined;
|
|
82
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
83
|
+
// Check if this is a retryable connection error
|
|
84
|
+
if (this.isRetryableError(error)) {
|
|
85
|
+
if (this.retryCount < this.maxRetries) {
|
|
86
|
+
this.retryCount++;
|
|
87
|
+
// Clean up the current request to avoid socket leaks
|
|
88
|
+
req.destroy();
|
|
89
|
+
const delayMs = this.calculateBackoffDelay();
|
|
90
|
+
await this.delay(delayMs);
|
|
91
|
+
// Query server to find out what the last chunk it received was
|
|
92
|
+
const serverLastChunk = await this.queryServerLastChunkIndex();
|
|
93
|
+
// Resume from the next chunk after what the server has
|
|
94
|
+
const resumeFromChunk = serverLastChunk + 1;
|
|
95
|
+
resolve(this.makeRequest(resumeFromChunk));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
reject(error);
|
|
100
|
+
});
|
|
101
|
+
req.on("timeout", async () => {
|
|
102
|
+
// Timeout is retryable
|
|
103
|
+
if (this.retryCount < this.maxRetries) {
|
|
104
|
+
this.retryCount++;
|
|
105
|
+
// Clean up the current request to avoid socket leaks
|
|
106
|
+
req.destroy();
|
|
107
|
+
const delayMs = this.calculateBackoffDelay();
|
|
108
|
+
await this.delay(delayMs);
|
|
109
|
+
// Query server to find where to resume
|
|
110
|
+
const serverLastChunk = await this.queryServerLastChunkIndex();
|
|
111
|
+
const resumeFromChunk = serverLastChunk + 1;
|
|
112
|
+
resolve(this.makeRequest(resumeFromChunk));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
req.destroy();
|
|
116
|
+
reject(new Error("Request timed out"));
|
|
117
|
+
});
|
|
118
|
+
req.on("response", async (res) => {
|
|
119
|
+
// Check for retryable status codes (408, 429, 5xx)
|
|
120
|
+
if (res.statusCode && this.isRetryableStatusCode(res.statusCode)) {
|
|
121
|
+
if (this.retryCount < this.maxRetries) {
|
|
122
|
+
this.retryCount++;
|
|
123
|
+
// Drain and destroy the response and request to avoid socket leaks
|
|
124
|
+
// We need to consume the response before destroying it
|
|
125
|
+
res.resume(); // Start draining the response
|
|
126
|
+
res.destroy(); // Destroy the response to free the socket
|
|
127
|
+
req.destroy(); // Destroy the request as well
|
|
128
|
+
const delayMs = this.calculateBackoffDelay();
|
|
129
|
+
await this.delay(delayMs);
|
|
130
|
+
// Query server to find where to resume (in case some data was written)
|
|
131
|
+
const serverLastChunk = await this.queryServerLastChunkIndex();
|
|
132
|
+
const resumeFromChunk = serverLastChunk + 1;
|
|
133
|
+
resolve(this.makeRequest(resumeFromChunk));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
res.destroy();
|
|
137
|
+
req.destroy();
|
|
138
|
+
reject(new Error(`Max retries (${this.maxRetries}) exceeded for status code ${res.statusCode}`));
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
// Non-retryable error status
|
|
142
|
+
if (res.statusCode && (res.statusCode < 200 || res.statusCode >= 300)) {
|
|
143
|
+
res.destroy();
|
|
144
|
+
req.destroy();
|
|
145
|
+
const error = new Error(`HTTP error! status: ${res.statusCode}`);
|
|
146
|
+
reject(error);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
// Success! Reset retry count
|
|
150
|
+
this.retryCount = 0;
|
|
151
|
+
res.on("end", () => {
|
|
152
|
+
resolve();
|
|
153
|
+
});
|
|
154
|
+
res.resume();
|
|
155
|
+
});
|
|
156
|
+
if (this.options.signal) {
|
|
157
|
+
this.options.signal.addEventListener("abort", () => {
|
|
158
|
+
req.destroy(new Error("Request aborted"));
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
const processStream = async () => {
|
|
162
|
+
try {
|
|
163
|
+
let lastSentIndex = startFromChunk - 1;
|
|
164
|
+
while (true) {
|
|
165
|
+
// Send all chunks that are available in buffer
|
|
166
|
+
while (lastSentIndex < this.highestBufferedIndex) {
|
|
167
|
+
lastSentIndex++;
|
|
168
|
+
const chunk = this.ringBuffer.find((c) => c.index === lastSentIndex);
|
|
169
|
+
if (chunk) {
|
|
170
|
+
const stringified = JSON.stringify(chunk.data) + "\n";
|
|
171
|
+
req.write(stringified);
|
|
172
|
+
this.currentChunkIndex = lastSentIndex + 1;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// If stream is complete and we've sent all buffered chunks, we're done
|
|
176
|
+
if (this.streamComplete && lastSentIndex >= this.highestBufferedIndex) {
|
|
177
|
+
req.end();
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
// Wait a bit for more chunks to be buffered
|
|
181
|
+
await this.delay(10);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
reject(error);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
processStream().catch((error) => {
|
|
189
|
+
reject(error);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
async initializeServerStream() {
|
|
194
|
+
await this.makeRequest(0);
|
|
195
|
+
}
|
|
196
|
+
async wait() {
|
|
197
|
+
return this.streamPromise;
|
|
198
|
+
}
|
|
199
|
+
[Symbol.asyncIterator]() {
|
|
200
|
+
return streamToAsyncIterator(this.consumerStream);
|
|
201
|
+
}
|
|
202
|
+
buildUrl() {
|
|
203
|
+
return `${this.options.baseUrl}/realtime/v1/streams/${this.options.runId}/${this.options.target ?? "self"}/${this.options.key}`;
|
|
204
|
+
}
|
|
205
|
+
isRetryableError(error) {
|
|
206
|
+
if (!error)
|
|
207
|
+
return false;
|
|
208
|
+
// Connection errors that are safe to retry
|
|
209
|
+
const retryableErrors = [
|
|
210
|
+
"ECONNRESET", // Connection reset by peer
|
|
211
|
+
"ECONNREFUSED", // Connection refused
|
|
212
|
+
"ETIMEDOUT", // Connection timed out
|
|
213
|
+
"ENOTFOUND", // DNS lookup failed
|
|
214
|
+
"EPIPE", // Broken pipe
|
|
215
|
+
"EHOSTUNREACH", // Host unreachable
|
|
216
|
+
"ENETUNREACH", // Network unreachable
|
|
217
|
+
"socket hang up", // Socket hang up
|
|
218
|
+
];
|
|
219
|
+
// Check error code
|
|
220
|
+
if (error.code && retryableErrors.includes(error.code)) {
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
// Check error message for socket hang up
|
|
224
|
+
if (error.message && error.message.includes("socket hang up")) {
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
isRetryableStatusCode(statusCode) {
|
|
230
|
+
// Retry on transient server errors
|
|
231
|
+
if (statusCode === 408)
|
|
232
|
+
return true; // Request Timeout
|
|
233
|
+
if (statusCode === 429)
|
|
234
|
+
return true; // Rate Limit
|
|
235
|
+
if (statusCode === 500)
|
|
236
|
+
return true; // Internal Server Error
|
|
237
|
+
if (statusCode === 502)
|
|
238
|
+
return true; // Bad Gateway
|
|
239
|
+
if (statusCode === 503)
|
|
240
|
+
return true; // Service Unavailable
|
|
241
|
+
if (statusCode === 504)
|
|
242
|
+
return true; // Gateway Timeout
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
async delay(ms) {
|
|
246
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
247
|
+
}
|
|
248
|
+
calculateBackoffDelay() {
|
|
249
|
+
// Exponential backoff with jitter: baseDelay * 2^retryCount + random jitter
|
|
250
|
+
const exponentialDelay = this.baseDelayMs * Math.pow(2, this.retryCount);
|
|
251
|
+
const jitter = Math.random() * 1000; // 0-1000ms jitter
|
|
252
|
+
return Math.min(exponentialDelay + jitter, this.maxDelayMs);
|
|
253
|
+
}
|
|
254
|
+
addToRingBuffer(index, data) {
|
|
255
|
+
const chunk = { index, data };
|
|
256
|
+
if (this.ringBuffer.length < this.maxBufferSize) {
|
|
257
|
+
// Buffer not full yet, just append
|
|
258
|
+
this.ringBuffer.push(chunk);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
// Buffer full, replace oldest chunk (ring buffer behavior)
|
|
262
|
+
const bufferIndex = index % this.maxBufferSize;
|
|
263
|
+
this.ringBuffer[bufferIndex] = chunk;
|
|
264
|
+
this.bufferStartIndex = Math.max(this.bufferStartIndex, index - this.maxBufferSize + 1);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
getChunksFromBuffer(startIndex) {
|
|
268
|
+
const result = [];
|
|
269
|
+
for (const chunk of this.ringBuffer) {
|
|
270
|
+
if (chunk.index >= startIndex) {
|
|
271
|
+
result.push(chunk);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
// Sort by index to ensure correct order
|
|
275
|
+
result.sort((a, b) => a.index - b.index);
|
|
276
|
+
return result;
|
|
277
|
+
}
|
|
278
|
+
async queryServerLastChunkIndex(attempt = 0) {
|
|
279
|
+
return new Promise((resolve, reject) => {
|
|
280
|
+
const url = new URL(this.buildUrl());
|
|
281
|
+
const maxHeadRetries = 3; // Separate retry limit for HEAD requests
|
|
282
|
+
const requestFn = url.protocol === "https:" ? httpsRequest : httpRequest;
|
|
283
|
+
const req = requestFn({
|
|
284
|
+
method: "HEAD",
|
|
285
|
+
hostname: url.hostname,
|
|
286
|
+
port: url.port || (url.protocol === "https:" ? 443 : 80),
|
|
287
|
+
path: url.pathname + url.search,
|
|
288
|
+
headers: {
|
|
289
|
+
...this.options.headers,
|
|
290
|
+
"X-Client-Id": this.clientId,
|
|
291
|
+
"X-Stream-Version": this.options.version ?? "v1",
|
|
292
|
+
},
|
|
293
|
+
timeout: 5000, // 5 second timeout for HEAD request
|
|
294
|
+
});
|
|
295
|
+
req.on("error", async (error) => {
|
|
296
|
+
if (this.isRetryableError(error) && attempt < maxHeadRetries) {
|
|
297
|
+
// Clean up the current request to avoid socket leaks
|
|
298
|
+
req.destroy();
|
|
299
|
+
await this.delay(1000 * (attempt + 1)); // Simple linear backoff
|
|
300
|
+
const result = await this.queryServerLastChunkIndex(attempt + 1);
|
|
301
|
+
resolve(result);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
req.destroy();
|
|
305
|
+
// Return -1 to indicate we don't know what the server has (resume from 0)
|
|
306
|
+
resolve(-1);
|
|
307
|
+
});
|
|
308
|
+
req.on("timeout", async () => {
|
|
309
|
+
req.destroy();
|
|
310
|
+
if (attempt < maxHeadRetries) {
|
|
311
|
+
await this.delay(1000 * (attempt + 1));
|
|
312
|
+
const result = await this.queryServerLastChunkIndex(attempt + 1);
|
|
313
|
+
resolve(result);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
resolve(-1);
|
|
317
|
+
});
|
|
318
|
+
req.on("response", async (res) => {
|
|
319
|
+
// Retry on 5xx errors
|
|
320
|
+
if (res.statusCode && this.isRetryableStatusCode(res.statusCode)) {
|
|
321
|
+
if (attempt < maxHeadRetries) {
|
|
322
|
+
// Drain and destroy the response and request to avoid socket leaks
|
|
323
|
+
res.resume();
|
|
324
|
+
res.destroy();
|
|
325
|
+
req.destroy();
|
|
326
|
+
await this.delay(1000 * (attempt + 1));
|
|
327
|
+
const result = await this.queryServerLastChunkIndex(attempt + 1);
|
|
328
|
+
resolve(result);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
res.destroy();
|
|
332
|
+
req.destroy();
|
|
333
|
+
resolve(-1);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
// Non-retryable error
|
|
337
|
+
if (res.statusCode && (res.statusCode < 200 || res.statusCode >= 300)) {
|
|
338
|
+
res.destroy();
|
|
339
|
+
req.destroy();
|
|
340
|
+
resolve(-1);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
// Success - extract chunk index
|
|
344
|
+
const lastChunkHeader = res.headers["x-last-chunk-index"];
|
|
345
|
+
if (lastChunkHeader) {
|
|
346
|
+
const lastChunkIndex = parseInt(Array.isArray(lastChunkHeader) ? lastChunkHeader[0] ?? "0" : lastChunkHeader ?? "0", 10);
|
|
347
|
+
resolve(lastChunkIndex);
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
resolve(-1);
|
|
351
|
+
}
|
|
352
|
+
res.resume(); // Consume response
|
|
353
|
+
});
|
|
354
|
+
req.end();
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
async function* streamToAsyncIterator(stream) {
|
|
359
|
+
const reader = stream.getReader();
|
|
360
|
+
try {
|
|
361
|
+
while (true) {
|
|
362
|
+
const { done, value } = await reader.read();
|
|
363
|
+
if (done)
|
|
364
|
+
return;
|
|
365
|
+
yield value;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
finally {
|
|
369
|
+
safeReleaseLock(reader);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
function safeReleaseLock(reader) {
|
|
373
|
+
try {
|
|
374
|
+
reader.releaseLock();
|
|
375
|
+
}
|
|
376
|
+
catch (error) { }
|
|
377
|
+
}
|
|
378
|
+
//# sourceMappingURL=streamsWriterV1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamsWriterV1.js","sourceRoot":"","sources":["../../../../src/v3/realtimeStreams/streamsWriterV1.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { StreamsWriter } from "./types.js";
|
|
2
|
+
export type StreamsWriterV2Options<T = any> = {
|
|
3
|
+
basin: string;
|
|
4
|
+
stream: string;
|
|
5
|
+
accessToken: string;
|
|
6
|
+
source: ReadableStream<T>;
|
|
7
|
+
signal?: AbortSignal;
|
|
8
|
+
flushIntervalMs?: number;
|
|
9
|
+
maxRetries?: number;
|
|
10
|
+
debug?: boolean;
|
|
11
|
+
maxQueuedBytes?: number;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* StreamsWriterV2 writes metadata stream data directly to S2 (https://s2.dev).
|
|
15
|
+
*
|
|
16
|
+
* Features:
|
|
17
|
+
* - Direct streaming: Uses S2's appendSession for efficient streaming
|
|
18
|
+
* - Automatic batching: Uses BatchTransform to batch records
|
|
19
|
+
* - No manual buffering: S2 handles buffering internally
|
|
20
|
+
* - Debug logging: Enable with debug: true to see detailed operation logs
|
|
21
|
+
*
|
|
22
|
+
* Example usage:
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const stream = new StreamsWriterV2({
|
|
25
|
+
* basin: "my-basin",
|
|
26
|
+
* stream: "my-stream",
|
|
27
|
+
* accessToken: "s2-token-here",
|
|
28
|
+
* source: myAsyncIterable,
|
|
29
|
+
* flushIntervalMs: 200, // Optional: batch linger duration in ms
|
|
30
|
+
* debug: true, // Optional: enable debug logging
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* // Wait for streaming to complete
|
|
34
|
+
* await stream.wait();
|
|
35
|
+
*
|
|
36
|
+
* // Or consume the stream
|
|
37
|
+
* for await (const value of stream) {
|
|
38
|
+
* console.log(value);
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare class StreamsWriterV2<T = any> implements StreamsWriter {
|
|
43
|
+
private options;
|
|
44
|
+
private s2Client;
|
|
45
|
+
private serverStream;
|
|
46
|
+
private consumerStream;
|
|
47
|
+
private streamPromise;
|
|
48
|
+
private readonly flushIntervalMs;
|
|
49
|
+
private readonly debug;
|
|
50
|
+
private readonly maxQueuedBytes;
|
|
51
|
+
private aborted;
|
|
52
|
+
private sessionWritable;
|
|
53
|
+
constructor(options: StreamsWriterV2Options<T>);
|
|
54
|
+
private handleAbort;
|
|
55
|
+
private initializeServerStream;
|
|
56
|
+
wait(): Promise<void>;
|
|
57
|
+
[Symbol.asyncIterator](): AsyncIterableIterator<T>;
|
|
58
|
+
private log;
|
|
59
|
+
private logError;
|
|
60
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { S2, AppendRecord, BatchTransform } from "@s2-dev/streamstore";
|
|
2
|
+
import { nanoid } from "nanoid";
|
|
3
|
+
/**
|
|
4
|
+
* StreamsWriterV2 writes metadata stream data directly to S2 (https://s2.dev).
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Direct streaming: Uses S2's appendSession for efficient streaming
|
|
8
|
+
* - Automatic batching: Uses BatchTransform to batch records
|
|
9
|
+
* - No manual buffering: S2 handles buffering internally
|
|
10
|
+
* - Debug logging: Enable with debug: true to see detailed operation logs
|
|
11
|
+
*
|
|
12
|
+
* Example usage:
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const stream = new StreamsWriterV2({
|
|
15
|
+
* basin: "my-basin",
|
|
16
|
+
* stream: "my-stream",
|
|
17
|
+
* accessToken: "s2-token-here",
|
|
18
|
+
* source: myAsyncIterable,
|
|
19
|
+
* flushIntervalMs: 200, // Optional: batch linger duration in ms
|
|
20
|
+
* debug: true, // Optional: enable debug logging
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* // Wait for streaming to complete
|
|
24
|
+
* await stream.wait();
|
|
25
|
+
*
|
|
26
|
+
* // Or consume the stream
|
|
27
|
+
* for await (const value of stream) {
|
|
28
|
+
* console.log(value);
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export class StreamsWriterV2 {
|
|
33
|
+
options;
|
|
34
|
+
s2Client;
|
|
35
|
+
serverStream;
|
|
36
|
+
consumerStream;
|
|
37
|
+
streamPromise;
|
|
38
|
+
flushIntervalMs;
|
|
39
|
+
debug;
|
|
40
|
+
maxQueuedBytes;
|
|
41
|
+
aborted = false;
|
|
42
|
+
sessionWritable = null;
|
|
43
|
+
constructor(options) {
|
|
44
|
+
this.options = options;
|
|
45
|
+
this.debug = options.debug ?? false;
|
|
46
|
+
this.s2Client = new S2({ accessToken: options.accessToken });
|
|
47
|
+
this.flushIntervalMs = options.flushIntervalMs ?? 200;
|
|
48
|
+
this.maxQueuedBytes = options.maxQueuedBytes ?? 1024 * 1024 * 10; // 10MB default
|
|
49
|
+
this.log(`[S2MetadataStream] Initializing: basin=${options.basin}, stream=${options.stream}, flushIntervalMs=${this.flushIntervalMs}, maxQueuedBytes=${this.maxQueuedBytes}`);
|
|
50
|
+
// Check if already aborted
|
|
51
|
+
if (options.signal?.aborted) {
|
|
52
|
+
this.aborted = true;
|
|
53
|
+
this.log("[S2MetadataStream] Signal already aborted, skipping initialization");
|
|
54
|
+
this.serverStream = new ReadableStream();
|
|
55
|
+
this.consumerStream = new ReadableStream();
|
|
56
|
+
this.streamPromise = Promise.resolve();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// Set up abort signal handler
|
|
60
|
+
if (options.signal) {
|
|
61
|
+
options.signal.addEventListener("abort", () => {
|
|
62
|
+
this.log("[S2MetadataStream] Abort signal received");
|
|
63
|
+
this.handleAbort();
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
const [serverStream, consumerStream] = this.options.source.tee();
|
|
67
|
+
this.serverStream = serverStream;
|
|
68
|
+
this.consumerStream = consumerStream;
|
|
69
|
+
this.streamPromise = this.initializeServerStream();
|
|
70
|
+
}
|
|
71
|
+
handleAbort() {
|
|
72
|
+
if (this.aborted) {
|
|
73
|
+
return; // Already aborted
|
|
74
|
+
}
|
|
75
|
+
this.aborted = true;
|
|
76
|
+
this.log("[S2MetadataStream] Handling abort - cleaning up resources");
|
|
77
|
+
// Abort the writable stream if it exists
|
|
78
|
+
if (this.sessionWritable) {
|
|
79
|
+
this.sessionWritable
|
|
80
|
+
.abort("Aborted")
|
|
81
|
+
.catch((error) => {
|
|
82
|
+
this.logError("[S2MetadataStream] Error aborting writable stream:", error);
|
|
83
|
+
})
|
|
84
|
+
.finally(() => {
|
|
85
|
+
this.log("[S2MetadataStream] Writable stream aborted");
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
this.log("[S2MetadataStream] Abort cleanup complete");
|
|
89
|
+
}
|
|
90
|
+
async initializeServerStream() {
|
|
91
|
+
try {
|
|
92
|
+
if (this.aborted) {
|
|
93
|
+
this.log("[S2MetadataStream] Stream initialization aborted");
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
this.log("[S2MetadataStream] Getting S2 basin and stream");
|
|
97
|
+
const basin = this.s2Client.basin(this.options.basin);
|
|
98
|
+
const stream = basin.stream(this.options.stream);
|
|
99
|
+
const session = await stream.appendSession({
|
|
100
|
+
maxQueuedBytes: this.maxQueuedBytes,
|
|
101
|
+
});
|
|
102
|
+
this.sessionWritable = session.writable;
|
|
103
|
+
this.log(`[S2MetadataStream] Starting stream pipeline`);
|
|
104
|
+
// Convert source stream to AppendRecord format and pipe to S2
|
|
105
|
+
await this.serverStream
|
|
106
|
+
.pipeThrough(new TransformStream({
|
|
107
|
+
transform: (chunk, controller) => {
|
|
108
|
+
if (this.aborted) {
|
|
109
|
+
controller.error(new Error("Stream aborted"));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
// Convert each chunk to JSON string and wrap in AppendRecord
|
|
113
|
+
controller.enqueue(AppendRecord.make(JSON.stringify({ data: chunk, id: nanoid(7) })));
|
|
114
|
+
},
|
|
115
|
+
}))
|
|
116
|
+
.pipeThrough(new BatchTransform({
|
|
117
|
+
lingerDurationMillis: this.flushIntervalMs,
|
|
118
|
+
}))
|
|
119
|
+
.pipeTo(session.writable);
|
|
120
|
+
this.log("[S2MetadataStream] Stream pipeline completed successfully");
|
|
121
|
+
// Get final position to verify completion
|
|
122
|
+
const lastAcked = session.lastAckedPosition();
|
|
123
|
+
if (lastAcked?.end) {
|
|
124
|
+
const recordsWritten = lastAcked.end.seq_num;
|
|
125
|
+
this.log(`[S2MetadataStream] Written ${recordsWritten} records, ending at seq_num=${lastAcked.end.seq_num}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
if (this.aborted) {
|
|
130
|
+
this.log("[S2MetadataStream] Stream error occurred but stream was aborted");
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
this.logError("[S2MetadataStream] Error in stream pipeline:", error);
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async wait() {
|
|
138
|
+
await this.streamPromise;
|
|
139
|
+
}
|
|
140
|
+
[Symbol.asyncIterator]() {
|
|
141
|
+
return streamToAsyncIterator(this.consumerStream);
|
|
142
|
+
}
|
|
143
|
+
// Helper methods
|
|
144
|
+
log(message) {
|
|
145
|
+
if (this.debug) {
|
|
146
|
+
console.log(message);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
logError(message, error) {
|
|
150
|
+
if (this.debug) {
|
|
151
|
+
console.error(message, error);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async function* streamToAsyncIterator(stream) {
|
|
156
|
+
const reader = stream.getReader();
|
|
157
|
+
try {
|
|
158
|
+
while (true) {
|
|
159
|
+
const { done, value } = await reader.read();
|
|
160
|
+
if (done)
|
|
161
|
+
return;
|
|
162
|
+
yield value;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
safeReleaseLock(reader);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function safeReleaseLock(reader) {
|
|
170
|
+
try {
|
|
171
|
+
reader.releaseLock();
|
|
172
|
+
}
|
|
173
|
+
catch (error) { }
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=streamsWriterV2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamsWriterV2.js","sourceRoot":"","sources":["../../../../src/v3/realtimeStreams/streamsWriterV2.ts"],"names":[],"mappings":"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"}
|