hammerkit 1.27.0-next.11 → 1.27.0-next.12
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/cli.js +1 -0
- package/dist/executer/deadline.js +17 -3
- package/dist/executer/execute-work-task.js +1 -1
- package/dist/harness/sandbox-client.js +2 -1
- package/dist/program.js +4 -0
- package/dist/remote/remote-work-commands.js +3 -2
- package/dist/server/run-request.js +2 -0
- package/dist/server/run-worker.js +1 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -79,6 +79,7 @@ class Cli {
|
|
|
79
79
|
explain: options?.explain ?? false,
|
|
80
80
|
cacheReadOnly: options?.cacheReadOnly ?? false,
|
|
81
81
|
timeout: options?.timeout ?? null,
|
|
82
|
+
maxTimeout: options?.maxTimeout ?? null,
|
|
82
83
|
skipDeps: options?.skipDeps ?? true,
|
|
83
84
|
wait: options?.wait ?? 'ready',
|
|
84
85
|
resourceCheck: options?.resourceCheck ?? true,
|
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.withDeadline = void 0;
|
|
3
|
+
exports.withDeadline = exports.getTaskTimeout = void 0;
|
|
4
4
|
const abort_event_1 = require("../utils/abort-event");
|
|
5
|
+
// How long a task may run: its own `timeout`, else the run's default (`--timeout`), and
|
|
6
|
+
// never longer than the run's cap (`--max-timeout`), which also covers tasks with a
|
|
7
|
+
// longer timeout of their own. A caller can shorten a task this way, never extend it.
|
|
8
|
+
function getTaskTimeout(own, run) {
|
|
9
|
+
const timeout = own ?? run.timeout;
|
|
10
|
+
if (run.maxTimeout === null) {
|
|
11
|
+
return timeout;
|
|
12
|
+
}
|
|
13
|
+
return timeout === null ? run.maxTimeout : Math.min(timeout, run.maxTimeout);
|
|
14
|
+
}
|
|
15
|
+
exports.getTaskTimeout = getTaskTimeout;
|
|
16
|
+
// the longest delay of setTimeout: Node fires a longer one after 1 ms
|
|
17
|
+
const MAX_TIMER_MS = 2 ** 31 - 1;
|
|
5
18
|
// An abort signal that follows `parent` and additionally fires after `timeout`
|
|
6
|
-
// ms, so a task deadline reuses the runtimes' existing abort/cleanup path.
|
|
19
|
+
// ms, so a task deadline reuses the runtimes' existing abort/cleanup path. A
|
|
20
|
+
// timeout beyond what a timer can wait (about 24.8 days) sets no deadline.
|
|
7
21
|
function withDeadline(parent, timeout) {
|
|
8
22
|
const controller = new AbortController();
|
|
9
23
|
let expired = false;
|
|
10
24
|
const parentListener = (0, abort_event_1.listenOnAbort)(parent, () => controller.abort());
|
|
11
|
-
const timer = timeout === null
|
|
25
|
+
const timer = timeout === null || timeout > MAX_TIMER_MS
|
|
12
26
|
? null
|
|
13
27
|
: setTimeout(() => {
|
|
14
28
|
expired = true;
|
|
@@ -94,7 +94,7 @@ dependents = null) {
|
|
|
94
94
|
stateKey: cacheState.stateKey,
|
|
95
95
|
started,
|
|
96
96
|
});
|
|
97
|
-
const timeout = work.data.timeout
|
|
97
|
+
const timeout = (0, deadline_1.getTaskTimeout)(work.data.timeout, options);
|
|
98
98
|
const deadline = (0, deadline_1.withDeadline)(abort, timeout);
|
|
99
99
|
try {
|
|
100
100
|
await work.runtime.execute(environment, {
|
|
@@ -115,7 +115,8 @@ class SandboxClient {
|
|
|
115
115
|
runOptions.args = options.args;
|
|
116
116
|
}
|
|
117
117
|
if (options.timeoutSeconds) {
|
|
118
|
-
|
|
118
|
+
// a cap: it also shortens a shell task that sets a longer timeout of its own
|
|
119
|
+
runOptions.maxTimeout = `${Math.max(1, Math.ceil(options.timeoutSeconds))}s`;
|
|
119
120
|
}
|
|
120
121
|
const submitted = await submitRun(this.connection, {
|
|
121
122
|
definition: this.build.hash,
|
package/dist/program.js
CHANGED
|
@@ -608,6 +608,7 @@ async function getProgram(environment, argv) {
|
|
|
608
608
|
.choices(['checksum', 'modify-date', 'none']))
|
|
609
609
|
.addOption(new commander_1.Option('--cache-read-only', `restore from cache backends but never push to them (or set ${read_only_1.CACHE_READ_ONLY_ENV}=1)`).default(false))
|
|
610
610
|
.addOption(new commander_1.Option('--timeout <duration>', 'fail tasks without their own timeout after this long (e.g. 10m)').argParser(units_1.parseDuration))
|
|
611
|
+
.addOption(new commander_1.Option('--max-timeout <duration>', 'fail any task after this long, also one with a longer timeout of its own (e.g. 2m)').argParser(units_1.parseDuration))
|
|
611
612
|
.addOption(new commander_1.Option('--network <level>', 'the most any task or service reaches besides its needs: none, open or allow:<host>,<host>').argParser(parseNetworkArgument))
|
|
612
613
|
.action(async (options, command) => {
|
|
613
614
|
try {
|
|
@@ -626,6 +627,7 @@ async function getProgram(environment, argv) {
|
|
|
626
627
|
wait: options.wait,
|
|
627
628
|
cacheReadOnly: (0, read_only_1.isCacheReadOnly)(options.cacheReadOnly, environment.processEnvs),
|
|
628
629
|
timeout: options.timeout ?? null,
|
|
630
|
+
maxTimeout: options.maxTimeout ?? null,
|
|
629
631
|
network: options.network ?? null,
|
|
630
632
|
});
|
|
631
633
|
if (!result.success) {
|
|
@@ -688,6 +690,7 @@ async function getProgram(environment, argv) {
|
|
|
688
690
|
.addOption(new commander_1.Option('--dry-run', 'print the execution plan with predicted cache hits/misses without running').default(false))
|
|
689
691
|
.addOption(new commander_1.Option('--cache-read-only', `restore from cache backends but never push to them (or set ${read_only_1.CACHE_READ_ONLY_ENV}=1)`).default(false))
|
|
690
692
|
.addOption(new commander_1.Option('--timeout <duration>', 'fail tasks without their own timeout after this long (e.g. 10m)').argParser(units_1.parseDuration))
|
|
693
|
+
.addOption(new commander_1.Option('--max-timeout <duration>', 'fail any task after this long, also one with a longer timeout of its own (e.g. 2m)').argParser(units_1.parseDuration))
|
|
691
694
|
.addOption(new commander_1.Option('--network <level>', 'the most any task or service reaches besides its needs: none, open or allow:<host>,<host>').argParser(parseNetworkArgument))
|
|
692
695
|
.addOption(new commander_1.Option('--no-skip-deps', 'run dependencies even when nothing needing them has to run'))
|
|
693
696
|
.action(async (task, options, command) => {
|
|
@@ -722,6 +725,7 @@ async function getProgram(environment, argv) {
|
|
|
722
725
|
explain: options.explain,
|
|
723
726
|
cacheReadOnly: (0, read_only_1.isCacheReadOnly)(options.cacheReadOnly, environment.processEnvs),
|
|
724
727
|
timeout: options.timeout ?? null,
|
|
728
|
+
maxTimeout: options.maxTimeout ?? null,
|
|
725
729
|
network: options.network ?? null,
|
|
726
730
|
skipDeps: options.skipDeps !== false,
|
|
727
731
|
});
|
|
@@ -139,7 +139,8 @@ function registerWorkCommands(remote, context) {
|
|
|
139
139
|
.addOption(new commander_1.Option('--commit <sha>', 'the commit the ref has to be at, else the run is refused; the commit checked out here when --ref is left out'))
|
|
140
140
|
.addOption(new commander_1.Option('--env <name>', 'the environment of the build file, as --env of run'))
|
|
141
141
|
.addOption(new commander_1.Option('--cache <method>', 'as --cache of run').choices(['checksum', 'modify-date', 'none']))
|
|
142
|
-
.addOption(new commander_1.Option('--timeout <duration>', '
|
|
142
|
+
.addOption(new commander_1.Option('--timeout <duration>', 'as --timeout of run: for tasks without their own, such as 30m'))
|
|
143
|
+
.addOption(new commander_1.Option('--max-timeout <duration>', 'as --max-timeout of run: for every task, also one with its own timeout'))
|
|
143
144
|
.action(guarded('Remote run was not successful', async (tasks, options) => {
|
|
144
145
|
const named = options.build ?? environment.processEnvs.HAMMERKIT_BUILD;
|
|
145
146
|
const definition = named ?? (0, bundle_1.hashBundle)(await (0, collect_bundle_1.collectBundle)(buildFile, environment));
|
|
@@ -160,7 +161,7 @@ function registerWorkCommands(remote, context) {
|
|
|
160
161
|
const { name: serverName, server } = await getServer(options.server);
|
|
161
162
|
const connection = { url: server.url, ...(0, token_source_1.getTokenSource)(environment, serverName, server) };
|
|
162
163
|
const runOptions = {};
|
|
163
|
-
for (const key of ['env', 'cache', 'timeout']) {
|
|
164
|
+
for (const key of ['env', 'cache', 'timeout', 'maxTimeout']) {
|
|
164
165
|
if (options[key] !== undefined) {
|
|
165
166
|
runOptions[key] = options[key];
|
|
166
167
|
}
|
|
@@ -38,6 +38,8 @@ exports.runOptionsSchema = zod_1.z
|
|
|
38
38
|
cacheReadOnly: zod_1.z.boolean().optional(),
|
|
39
39
|
// as --timeout
|
|
40
40
|
timeout: duration.optional(),
|
|
41
|
+
// as --max-timeout: caps every task, also one with a longer timeout of its own
|
|
42
|
+
maxTimeout: duration.optional(),
|
|
41
43
|
// as --no-skip-deps when false
|
|
42
44
|
skipDeps: zod_1.z.boolean().optional(),
|
|
43
45
|
// as the text after `--`: appended to the last command of the one task the run
|
|
@@ -120,6 +120,7 @@ cancelled, emit) {
|
|
|
120
120
|
cacheDefault: options.cache ?? 'checksum',
|
|
121
121
|
cacheReadOnly: options.cacheReadOnly ?? false,
|
|
122
122
|
timeout: options.timeout ? (0, units_1.parseDuration)(options.timeout) : null,
|
|
123
|
+
maxTimeout: options.maxTimeout ? (0, units_1.parseDuration)(options.maxTimeout) : null,
|
|
123
124
|
skipDeps: options.skipDeps !== false,
|
|
124
125
|
network: getRunNetwork(input),
|
|
125
126
|
// why a task was not taken from the cache goes into its result
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hammerkit",
|
|
3
3
|
"description": "Containerized build tool with incremental caching that runs the same build file locally, in Docker and on Kubernetes.",
|
|
4
|
-
"version": "1.27.0-next.
|
|
4
|
+
"version": "1.27.0-next.12",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"build",
|
|
7
7
|
"build-tool",
|