apify-client 3.0.0-beta.50 → 3.0.0-beta.52
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/base/resource_client.js +13 -7
- package/dist/bundle.js +3 -3
- package/dist/bundle.js.map +1 -1
- package/dist/resource_clients/build.d.ts +1 -0
- package/dist/resource_clients/build.js +1 -0
- package/dist/resource_clients/log.d.ts +1 -1
- package/dist/resource_clients/log.js +36 -19
- package/dist/resource_clients/run.d.ts +1 -0
- package/dist/resource_clients/run.js +1 -0
- package/package.json +1 -1
|
@@ -98,6 +98,7 @@ export declare class BuildClient extends ResourceClient {
|
|
|
98
98
|
* Unlike the `waitForFinish` parameter in {@link get}, this method can wait indefinitely
|
|
99
99
|
* by polling the build status. It uses the `waitForFinish` parameter internally (max 60s per call)
|
|
100
100
|
* and continuously polls until the build finishes or the timeout is reached.
|
|
101
|
+
* Rejects with a {@link NotFoundError} if the build keeps returning 404 for 3 seconds.
|
|
101
102
|
*
|
|
102
103
|
* This is useful when you need to immediately start a run after a build finishes.
|
|
103
104
|
*
|
|
@@ -131,6 +131,7 @@ export class BuildClient extends ResourceClient {
|
|
|
131
131
|
* Unlike the `waitForFinish` parameter in {@link get}, this method can wait indefinitely
|
|
132
132
|
* by polling the build status. It uses the `waitForFinish` parameter internally (max 60s per call)
|
|
133
133
|
* and continuously polls until the build finishes or the timeout is reached.
|
|
134
|
+
* Rejects with a {@link NotFoundError} if the build keeps returning 404 for 3 seconds.
|
|
134
135
|
*
|
|
135
136
|
* This is useful when you need to immediately start a run after a build finishes.
|
|
136
137
|
*
|
|
@@ -5,6 +5,8 @@ import { ResourceClient } from '../base/resource_client.js';
|
|
|
5
5
|
import { timeoutOptionsShape } from '../timeouts.js';
|
|
6
6
|
import { cast, catchNotFoundForResourceOrThrow, concatBytes, parseArgument } from '../utils.js';
|
|
7
7
|
const logOptionsSchema = z.strictObject({ raw: z.boolean().optional(), ...timeoutOptionsShape });
|
|
8
|
+
/** How long `StreamedLog.stop()` waits for lines already in flight before aborting the log stream request. */
|
|
9
|
+
const STOP_GRACE_MILLIS = 1000;
|
|
8
10
|
/**
|
|
9
11
|
* Client for accessing Actor run or build logs.
|
|
10
12
|
*
|
|
@@ -141,6 +143,7 @@ export class StreamedLog {
|
|
|
141
143
|
#signal;
|
|
142
144
|
#streamingTask = null;
|
|
143
145
|
#stopLogging = false;
|
|
146
|
+
#stopController = new AbortController();
|
|
144
147
|
constructor(options) {
|
|
145
148
|
const { toLog, logClient, fromStart = true, signal } = options;
|
|
146
149
|
this.#destinationLog = toLog;
|
|
@@ -156,16 +159,19 @@ export class StreamedLog {
|
|
|
156
159
|
throw new Error('Streaming task already active');
|
|
157
160
|
}
|
|
158
161
|
this.#stopLogging = false;
|
|
162
|
+
this.#stopController = new AbortController();
|
|
159
163
|
this.#streamingTask = this.#streamLog();
|
|
160
164
|
}
|
|
161
165
|
/**
|
|
162
|
-
* Stop log redirection.
|
|
166
|
+
* Stop log redirection. Waits up to one second for lines already in flight, then aborts the log stream request.
|
|
163
167
|
*/
|
|
164
168
|
async stop() {
|
|
165
169
|
if (!this.#streamingTask) {
|
|
166
170
|
throw new Error('Streaming task is not active');
|
|
167
171
|
}
|
|
168
172
|
this.#stopLogging = true;
|
|
173
|
+
const stopController = this.#stopController;
|
|
174
|
+
const abortTimeout = setTimeout(() => stopController.abort(), STOP_GRACE_MILLIS);
|
|
169
175
|
try {
|
|
170
176
|
await this.#streamingTask;
|
|
171
177
|
}
|
|
@@ -175,6 +181,7 @@ export class StreamedLog {
|
|
|
175
181
|
}
|
|
176
182
|
}
|
|
177
183
|
finally {
|
|
184
|
+
clearTimeout(abortTimeout);
|
|
178
185
|
this.#streamingTask = null;
|
|
179
186
|
}
|
|
180
187
|
}
|
|
@@ -182,12 +189,15 @@ export class StreamedLog {
|
|
|
182
189
|
* Get log stream from response and redirect it to another log.
|
|
183
190
|
*/
|
|
184
191
|
async #streamLog() {
|
|
192
|
+
const signal = this.#signal
|
|
193
|
+
? AbortSignal.any([this.#signal, this.#stopController.signal])
|
|
194
|
+
: this.#stopController.signal;
|
|
185
195
|
try {
|
|
186
|
-
const logStream = await this.#logClient.stream({ raw: true, signal
|
|
196
|
+
const logStream = await this.#logClient.stream({ raw: true, signal });
|
|
187
197
|
if (!logStream) {
|
|
188
198
|
return;
|
|
189
199
|
}
|
|
190
|
-
const lastChunkRemainder = await this.#logStreamChunks(logStream);
|
|
200
|
+
const lastChunkRemainder = await this.#logStreamChunks(logStream, signal);
|
|
191
201
|
// Process whatever is left when exiting. Maybe it is incomplete, maybe it is last log without EOL.
|
|
192
202
|
const lastMessage = this.#decoder.decode(lastChunkRemainder).trim();
|
|
193
203
|
if (lastMessage.length) {
|
|
@@ -195,30 +205,37 @@ export class StreamedLog {
|
|
|
195
205
|
}
|
|
196
206
|
}
|
|
197
207
|
catch (err) {
|
|
198
|
-
if (
|
|
208
|
+
if (signal.aborted)
|
|
199
209
|
return;
|
|
200
210
|
log.warning(`Log redirection stopped due to error`, err);
|
|
201
211
|
}
|
|
202
212
|
}
|
|
203
|
-
async #logStreamChunks(logStream) {
|
|
213
|
+
async #logStreamChunks(logStream, signal) {
|
|
204
214
|
// Chunk may be incomplete. Keep remainder for next chunk.
|
|
205
215
|
let previousChunkRemainder = new Uint8Array();
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
216
|
+
try {
|
|
217
|
+
for await (const chunk of logStream) {
|
|
218
|
+
// Handle possible leftover incomplete line from previous chunk.
|
|
219
|
+
// Everything before last end of line is complete.
|
|
220
|
+
const chunkWithPreviousRemainder = new Uint8Array(previousChunkRemainder.length + chunk.length);
|
|
221
|
+
chunkWithPreviousRemainder.set(previousChunkRemainder, 0);
|
|
222
|
+
chunkWithPreviousRemainder.set(chunk, previousChunkRemainder.length);
|
|
223
|
+
const lastCompleteMessageIndex = chunkWithPreviousRemainder.lastIndexOf(0x0a);
|
|
224
|
+
previousChunkRemainder = chunkWithPreviousRemainder.slice(lastCompleteMessageIndex);
|
|
225
|
+
// Push complete part of the chunk to the buffer
|
|
226
|
+
this.#streamBuffer.push(chunkWithPreviousRemainder.slice(0, lastCompleteMessageIndex));
|
|
227
|
+
this.#logBufferContent();
|
|
228
|
+
// Keep processing the new data until stopped
|
|
229
|
+
if (this.#stopLogging) {
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
220
232
|
}
|
|
221
233
|
}
|
|
234
|
+
catch (err) {
|
|
235
|
+
// An aborted stream still hands back its unterminated last line, so the caller can flush it.
|
|
236
|
+
if (!signal.aborted)
|
|
237
|
+
throw err;
|
|
238
|
+
}
|
|
222
239
|
return previousChunkRemainder;
|
|
223
240
|
}
|
|
224
241
|
/**
|
|
@@ -202,6 +202,7 @@ export declare class RunClient extends ResourceClient {
|
|
|
202
202
|
* Unlike the `waitForFinish` parameter in {@link get}, this method can wait indefinitely
|
|
203
203
|
* by polling the run status. It uses the `waitForFinish` parameter internally (max 60s per call)
|
|
204
204
|
* and continuously polls until the run finishes or the timeout is reached.
|
|
205
|
+
* Rejects with a {@link NotFoundError} if the run keeps returning 404 for 3 seconds.
|
|
205
206
|
*
|
|
206
207
|
* @param options - Wait options
|
|
207
208
|
* @param options.waitSecs - Maximum time to wait for the run to finish, in seconds. If the limit is reached, the returned promise resolves to a run object that will have status `READY` or `RUNNING`. If omitted, waits indefinitely.
|
|
@@ -330,6 +330,7 @@ export class RunClient extends ResourceClient {
|
|
|
330
330
|
* Unlike the `waitForFinish` parameter in {@link get}, this method can wait indefinitely
|
|
331
331
|
* by polling the run status. It uses the `waitForFinish` parameter internally (max 60s per call)
|
|
332
332
|
* and continuously polls until the run finishes or the timeout is reached.
|
|
333
|
+
* Rejects with a {@link NotFoundError} if the run keeps returning 404 for 3 seconds.
|
|
333
334
|
*
|
|
334
335
|
* @param options - Wait options
|
|
335
336
|
* @param options.waitSecs - Maximum time to wait for the run to finish, in seconds. If the limit is reached, the returned promise resolves to a run object that will have status `READY` or `RUNNING`. If omitted, waits indefinitely.
|