Skip to content

Commit b1d8b3e

Browse files
committed
add pooling loop for push
1 parent d9bf8ed commit b1d8b3e

1 file changed

Lines changed: 28 additions & 12 deletions

File tree

src/commands/actors/push.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ import type { Actor, ActorCollectionCreateOptions, ActorDefaultRunOptions } from
66
import open from 'open';
77

88
import { fetchManifest } from '@apify/actor-templates';
9-
import { ACTOR_JOB_STATUSES, ACTOR_SOURCE_TYPES, MAX_MULTIFILE_BYTES } from '@apify/consts';
9+
import {
10+
ACTOR_JOB_STATUSES,
11+
ACTOR_JOB_TERMINAL_STATUSES,
12+
ACTOR_SOURCE_TYPES,
13+
MAX_MULTIFILE_BYTES,
14+
} from '@apify/consts';
1015
import { createHmacSignature } from '@apify/utilities';
1116

1217
import { ApifyCommand } from '../../lib/command-framework/apify-command.js';
@@ -358,18 +363,16 @@ Skipping push. Use --force to override.`,
358363
waitForFinish: 2, // NOTE: We need to wait some time to Apify open stream and we can create connection
359364
});
360365

361-
try {
362-
// While the log is streaming, forward interrupt signals to a
363-
// platform-side abort so the build doesn't keep running after the
364-
// user gives up waiting (Ctrl+C, SIGTERM from a parent process,
365-
// SIGHUP from a closing terminal). The `using` binding guarantees
366-
// the listener is removed before we poll for final status.
367-
using _signalHandler = useAbortJobOnSignal({
368-
apifyClient,
369-
kind: 'build',
370-
jobId: build.id,
371-
});
366+
// Forward interrupt signals (Ctrl+C, SIGTERM, SIGHUP) to a platform-side
367+
// abort for the lifetime of log streaming AND status polling, so the
368+
// build doesn't keep running after the user gives up waiting.
369+
using _signalHandler = useAbortJobOnSignal({
370+
apifyClient,
371+
kind: 'build',
372+
jobId: build.id,
373+
});
372374

375+
try {
373376
await outputJobLog({ job: build, timeoutMillis: waitForFinishMillis, apifyClient });
374377
} catch (err) {
375378
warning({ message: 'Can not get log:' });
@@ -378,6 +381,17 @@ Skipping push. Use --force to override.`,
378381

379382
build = (await apifyClient.build(build.id).get())!;
380383

384+
// `outputJobLog` can return before the build is actually terminal (stream
385+
// ended early, timeout hit). Poll so the status branches below see the
386+
// real outcome.
387+
if (waitForFinishMillis !== undefined) {
388+
const deadline = Date.now() + waitForFinishMillis;
389+
while (!ACTOR_JOB_TERMINAL_STATUSES.includes(build.status as never) && Date.now() < deadline) {
390+
await new Promise((resolve) => setTimeout(resolve, 1000));
391+
build = (await apifyClient.build(build.id).get())!;
392+
}
393+
}
394+
381395
if (this.flags.json) {
382396
printJsonToStdout(build);
383397
return;
@@ -402,9 +416,11 @@ Skipping push. Use --force to override.`,
402416
// @ts-expect-error FIX THESE TYPES 😢
403417
} else if (build.status === ACTOR_JOB_STATUSES.READY) {
404418
warning({ message: 'Build is waiting for allocation.' });
419+
process.exitCode = CommandExitCodes.BuildTimedOut;
405420
// @ts-expect-error FIX THESE TYPES 😢
406421
} else if (build.status === ACTOR_JOB_STATUSES.RUNNING) {
407422
warning({ message: 'Build is still running.' });
423+
process.exitCode = CommandExitCodes.BuildTimedOut;
408424
// @ts-expect-error FIX THESE TYPES 😢
409425
} else if (build.status === ACTOR_JOB_STATUSES.ABORTED || build.status === ACTOR_JOB_STATUSES.ABORTING) {
410426
warning({ message: 'Build was aborted!' });

0 commit comments

Comments
 (0)