@nmakarov/cli-toolkit 0.69.0 → 0.71.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/cli-runner.cjs +386 -192
- package/dist/cli-runner.cjs.map +1 -1
- package/dist/cli-runner.js +386 -192
- package/dist/cli-runner.js.map +1 -1
- package/dist/index.cjs +440 -208
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +430 -208
- package/dist/index.js.map +1 -1
- package/dist/init.cjs +129 -91
- package/dist/init.cjs.map +1 -1
- package/dist/init.js +129 -91
- package/dist/init.js.map +1 -1
- package/dist/screen.cjs +124 -90
- package/dist/screen.cjs.map +1 -1
- package/dist/screen.js +121 -90
- package/dist/screen.js.map +1 -1
- package/dist/tasks.cjs +308 -117
- package/dist/tasks.cjs.map +1 -1
- package/dist/tasks.js +301 -117
- package/dist/tasks.js.map +1 -1
- package/package.json +2 -2
package/dist/tasks.js
CHANGED
|
@@ -342,12 +342,13 @@ function tasksSchemaSpec(queueName = "tasks") {
|
|
|
342
342
|
}
|
|
343
343
|
};
|
|
344
344
|
}
|
|
345
|
-
function taskHistoryInsertFromQueueRow(row, overrides) {
|
|
345
|
+
function taskHistoryInsertFromQueueRow(row, overrides = {}) {
|
|
346
346
|
const { id, ...snapshot } = row;
|
|
347
|
-
void id;
|
|
347
|
+
const opid = overrides.opid !== void 0 ? overrides.opid : snapshot.opid != null && String(snapshot.opid).trim() !== "" ? snapshot.opid : id;
|
|
348
348
|
return {
|
|
349
349
|
...snapshot,
|
|
350
|
-
...overrides
|
|
350
|
+
...overrides,
|
|
351
|
+
opid
|
|
351
352
|
};
|
|
352
353
|
}
|
|
353
354
|
async function ensureTaskTables(context, options = {}) {
|
|
@@ -2686,69 +2687,6 @@ var TaskStopRunner = class extends AbstractTask {
|
|
|
2686
2687
|
}
|
|
2687
2688
|
};
|
|
2688
2689
|
|
|
2689
|
-
// src/tasks/coreTasks/TaskGetLogs.js
|
|
2690
|
-
var TaskGetLogs = class extends AbstractTask {
|
|
2691
|
-
/**
|
|
2692
|
-
* @param {object} context
|
|
2693
|
-
* @param {Record<string, unknown>} [overrides]
|
|
2694
|
-
* @returns {Promise<{ source: string, resource: string, tail: number, afterTs?: string }>}
|
|
2695
|
-
*/
|
|
2696
|
-
static async resolveCustomParams(context, overrides = {}) {
|
|
2697
|
-
const merged = AbstractTask._mergeTypedParams(context, "task-get-logs", {
|
|
2698
|
-
source: "string",
|
|
2699
|
-
resource: "string",
|
|
2700
|
-
tail: "number default 100",
|
|
2701
|
-
afterTs: "string"
|
|
2702
|
-
}, overrides);
|
|
2703
|
-
const source = typeof merged.source === "string" ? merged.source.trim() : "";
|
|
2704
|
-
const resource = typeof merged.resource === "string" ? merged.resource.trim() : "";
|
|
2705
|
-
if (!source) throw new ParamError('getLogs: param "source" is required');
|
|
2706
|
-
if (!resource) throw new ParamError('getLogs: param "resource" is required');
|
|
2707
|
-
let tail = Number(merged.tail);
|
|
2708
|
-
if (!Number.isFinite(tail) || tail < 1) tail = 100;
|
|
2709
|
-
tail = Math.min(1e4, Math.max(1, Math.floor(tail)));
|
|
2710
|
-
const out = { source, resource, tail };
|
|
2711
|
-
if (typeof merged.afterTs === "string" && merged.afterTs.trim()) {
|
|
2712
|
-
out.afterTs = merged.afterTs.trim();
|
|
2713
|
-
}
|
|
2714
|
-
return out;
|
|
2715
|
-
}
|
|
2716
|
-
/**
|
|
2717
|
-
* @param {unknown} _reportProgress Unused (single-shot read, no progress events).
|
|
2718
|
-
* @returns {Promise<{ success: boolean, results: unknown }>}
|
|
2719
|
-
*/
|
|
2720
|
-
async run(_reportProgress) {
|
|
2721
|
-
const p = this.task.params ?? {};
|
|
2722
|
-
const source = String(p.source ?? "").trim();
|
|
2723
|
-
const resource = String(p.resource ?? "").trim();
|
|
2724
|
-
const tail = Math.max(1, Math.min(1e4, Number(p.tail) > 0 ? Number(p.tail) : 100));
|
|
2725
|
-
const afterTs = p.afterTs != null && String(p.afterTs).trim() ? String(p.afterTs).trim() : null;
|
|
2726
|
-
if (!source || !resource) {
|
|
2727
|
-
return {
|
|
2728
|
-
success: false,
|
|
2729
|
-
results: { error: 'getLogs requires params "source" and "resource"' }
|
|
2730
|
-
};
|
|
2731
|
-
}
|
|
2732
|
-
try {
|
|
2733
|
-
const { records, latestTs } = await readTaskIpcLogsSnapshot(this.context, {
|
|
2734
|
-
source,
|
|
2735
|
-
resource,
|
|
2736
|
-
tail,
|
|
2737
|
-
afterTs
|
|
2738
|
-
});
|
|
2739
|
-
return {
|
|
2740
|
-
success: true,
|
|
2741
|
-
results: { records, latestTs, source, resource }
|
|
2742
|
-
};
|
|
2743
|
-
} catch (e) {
|
|
2744
|
-
return {
|
|
2745
|
-
success: false,
|
|
2746
|
-
results: { error: e?.message ?? String(e) }
|
|
2747
|
-
};
|
|
2748
|
-
}
|
|
2749
|
-
}
|
|
2750
|
-
};
|
|
2751
|
-
|
|
2752
2690
|
// src/tasks/runtimeParams.js
|
|
2753
2691
|
var LOOP_RUNTIME_KEYS = ["maxParallel", "pollMs", "claimJitterMs", "scanLimit"];
|
|
2754
2692
|
var LOGGER_RUNTIME_KEYS = [
|
|
@@ -2762,7 +2700,77 @@ var LOGGER_RUNTIME_KEYS = [
|
|
|
2762
2700
|
"progressWithTimes",
|
|
2763
2701
|
"progressThrottleMs"
|
|
2764
2702
|
];
|
|
2765
|
-
var
|
|
2703
|
+
var DEFAULT_RUNTIME_PARAM_SPECS = [
|
|
2704
|
+
{
|
|
2705
|
+
key: "maxParallel",
|
|
2706
|
+
type: "number",
|
|
2707
|
+
label: "Max parallel",
|
|
2708
|
+
description: "Worker-lane concurrency (how many tasks claim at once)"
|
|
2709
|
+
},
|
|
2710
|
+
{
|
|
2711
|
+
key: "pollMs",
|
|
2712
|
+
type: "number",
|
|
2713
|
+
label: "Poll ms",
|
|
2714
|
+
description: "Idle poll interval between claim attempts"
|
|
2715
|
+
},
|
|
2716
|
+
{
|
|
2717
|
+
key: "claimJitterMs",
|
|
2718
|
+
type: "number",
|
|
2719
|
+
label: "Claim jitter ms",
|
|
2720
|
+
description: "Random delay before worker claims (0 = off)"
|
|
2721
|
+
},
|
|
2722
|
+
{
|
|
2723
|
+
key: "scanLimit",
|
|
2724
|
+
type: "number",
|
|
2725
|
+
label: "Scan limit",
|
|
2726
|
+
description: "Max idle rows scanned per claim attempt"
|
|
2727
|
+
}
|
|
2728
|
+
];
|
|
2729
|
+
function mergeRuntimeParamSpecs(extra) {
|
|
2730
|
+
const byKey = new Map(DEFAULT_RUNTIME_PARAM_SPECS.map((s) => [s.key, { ...s }]));
|
|
2731
|
+
if (Array.isArray(extra)) {
|
|
2732
|
+
for (const raw of extra) {
|
|
2733
|
+
if (!raw || typeof raw !== "object") continue;
|
|
2734
|
+
const key = String(raw.key ?? "").trim();
|
|
2735
|
+
if (!key) continue;
|
|
2736
|
+
const prev = byKey.get(key) ?? {};
|
|
2737
|
+
const type = ["number", "boolean", "string"].includes(raw.type) ? raw.type : prev.type ?? "string";
|
|
2738
|
+
byKey.set(key, {
|
|
2739
|
+
key,
|
|
2740
|
+
type,
|
|
2741
|
+
label: String(raw.label ?? prev.label ?? key),
|
|
2742
|
+
description: raw.description != null ? String(raw.description) : prev.description != null ? String(prev.description) : void 0
|
|
2743
|
+
});
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
return Array.from(byKey.values());
|
|
2747
|
+
}
|
|
2748
|
+
function runtimeValuesForSpecs(context, specs = DEFAULT_RUNTIME_PARAM_SPECS) {
|
|
2749
|
+
const rt = ensureTasksRuntime(context);
|
|
2750
|
+
const out = {};
|
|
2751
|
+
for (const s of specs) {
|
|
2752
|
+
if (rt[s.key] !== void 0) out[s.key] = rt[s.key];
|
|
2753
|
+
}
|
|
2754
|
+
return out;
|
|
2755
|
+
}
|
|
2756
|
+
function runtimeParamSpecsFromMetadata(metadata) {
|
|
2757
|
+
const meta = metadata && typeof metadata === "object" ? metadata : null;
|
|
2758
|
+
const raw = meta?.runtimeParams;
|
|
2759
|
+
if (!Array.isArray(raw) || raw.length === 0) {
|
|
2760
|
+
return mergeRuntimeParamSpecs();
|
|
2761
|
+
}
|
|
2762
|
+
return mergeRuntimeParamSpecs(raw);
|
|
2763
|
+
}
|
|
2764
|
+
var CONTROL_LANE_TASK_NAMES = [
|
|
2765
|
+
"stopRunner",
|
|
2766
|
+
"stop",
|
|
2767
|
+
"pauseRunner",
|
|
2768
|
+
"pause",
|
|
2769
|
+
"unpauseRunner",
|
|
2770
|
+
"unpause",
|
|
2771
|
+
"setRuntimeParam",
|
|
2772
|
+
"setRunnerParam"
|
|
2773
|
+
];
|
|
2766
2774
|
function controlLaneTaskNames(extra) {
|
|
2767
2775
|
const names = [...CONTROL_LANE_TASK_NAMES];
|
|
2768
2776
|
if (extra == null || extra === "") return names;
|
|
@@ -2825,6 +2833,7 @@ function ensureTasksRuntime(context, seed = {}) {
|
|
|
2825
2833
|
if (rt.pollMs === void 0) rt.pollMs = seed.pollMs ?? 1e3;
|
|
2826
2834
|
if (rt.claimJitterMs === void 0) rt.claimJitterMs = seed.claimJitterMs ?? 0;
|
|
2827
2835
|
if (rt.scanLimit === void 0) rt.scanLimit = seed.scanLimit ?? 100;
|
|
2836
|
+
if (rt.paused === void 0) rt.paused = seed.paused === true;
|
|
2828
2837
|
return rt;
|
|
2829
2838
|
}
|
|
2830
2839
|
async function applyRuntimeParam(context, key, value) {
|
|
@@ -2848,12 +2857,15 @@ async function applyRuntimeParam(context, key, value) {
|
|
|
2848
2857
|
const reg = context.servicesRegistry;
|
|
2849
2858
|
if (reg?.rowId && reg?.registryTable) {
|
|
2850
2859
|
try {
|
|
2851
|
-
const
|
|
2860
|
+
const specs = Array.isArray(context.tasksRuntimeParamSpecs) ? context.tasksRuntimeParamSpecs : DEFAULT_RUNTIME_PARAM_SPECS;
|
|
2861
|
+
const runtimeSnapshot = runtimeValuesForSpecs(context, specs);
|
|
2852
2862
|
for (const lk of LOOP_RUNTIME_KEYS) {
|
|
2853
|
-
if (runtime[lk] !== void 0
|
|
2863
|
+
if (runtime[lk] !== void 0 && runtimeSnapshot[lk] === void 0) {
|
|
2864
|
+
runtimeSnapshot[lk] = runtime[lk];
|
|
2865
|
+
}
|
|
2854
2866
|
}
|
|
2855
2867
|
await updateServicesRegistryMetadata(context, reg, {
|
|
2856
|
-
runtime:
|
|
2868
|
+
runtime: runtimeSnapshot,
|
|
2857
2869
|
runtimeUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2858
2870
|
});
|
|
2859
2871
|
applied.push("servicesRegistry");
|
|
@@ -2889,6 +2901,140 @@ function readLoopRuntime(context) {
|
|
|
2889
2901
|
};
|
|
2890
2902
|
}
|
|
2891
2903
|
|
|
2904
|
+
// src/tasks/coreTasks/TaskPauseRunner.js
|
|
2905
|
+
async function applyRunnerPaused(context, paused) {
|
|
2906
|
+
const runtime = ensureTasksRuntime(context);
|
|
2907
|
+
const was = runtime.paused === true;
|
|
2908
|
+
runtime.paused = paused === true;
|
|
2909
|
+
const registry = context.servicesRegistry;
|
|
2910
|
+
if (registry && typeof registry === "object") {
|
|
2911
|
+
await updateServicesRegistryMetadata(context, registry, {
|
|
2912
|
+
paused: runtime.paused,
|
|
2913
|
+
pausedAt: runtime.paused ? (/* @__PURE__ */ new Date()).toISOString() : null
|
|
2914
|
+
});
|
|
2915
|
+
}
|
|
2916
|
+
const message = runtime.paused ? was ? "Runner already paused (no new worker tasks)." : "Runner paused: finishing in-flight work; no new worker tasks until unpause." : was ? "Runner unpaused: claiming worker tasks again." : "Runner already running (not paused).";
|
|
2917
|
+
context.logger?.warn?.(
|
|
2918
|
+
runtime.paused ? `[TaskPauseRunner] ${message}` : `[TaskUnpauseRunner] ${message}`
|
|
2919
|
+
);
|
|
2920
|
+
return {
|
|
2921
|
+
success: true,
|
|
2922
|
+
results: {
|
|
2923
|
+
paused: runtime.paused,
|
|
2924
|
+
message
|
|
2925
|
+
}
|
|
2926
|
+
};
|
|
2927
|
+
}
|
|
2928
|
+
var TaskPauseRunner = class extends AbstractTask {
|
|
2929
|
+
static taskName = "pauseRunner";
|
|
2930
|
+
static description = "Pause a runner: finish in-flight tasks, claim no new worker tasks until unpaused";
|
|
2931
|
+
static aliases = ["pause"];
|
|
2932
|
+
static defaultWaitForResult = true;
|
|
2933
|
+
/**
|
|
2934
|
+
* @param {object} context
|
|
2935
|
+
* @param {Record<string, unknown>} [overrides]
|
|
2936
|
+
* @returns {Promise<object>}
|
|
2937
|
+
*/
|
|
2938
|
+
static async resolveParams(context, overrides = {}) {
|
|
2939
|
+
const main = await super.resolveParams(context, overrides);
|
|
2940
|
+
if (!main.serviceName) {
|
|
2941
|
+
throw new ParamError(
|
|
2942
|
+
"pause/pauseRunner requires --serviceName (registry instance name; optional --serviceGroup, --instanceNumber, --serverName to narrow targeting)"
|
|
2943
|
+
);
|
|
2944
|
+
}
|
|
2945
|
+
return main;
|
|
2946
|
+
}
|
|
2947
|
+
async run() {
|
|
2948
|
+
return applyRunnerPaused(this.context, true);
|
|
2949
|
+
}
|
|
2950
|
+
};
|
|
2951
|
+
var TaskUnpauseRunner = class extends AbstractTask {
|
|
2952
|
+
static taskName = "unpauseRunner";
|
|
2953
|
+
static description = "Unpause a runner: resume claiming worker tasks";
|
|
2954
|
+
static aliases = ["unpause"];
|
|
2955
|
+
static defaultWaitForResult = true;
|
|
2956
|
+
/**
|
|
2957
|
+
* @param {object} context
|
|
2958
|
+
* @param {Record<string, unknown>} [overrides]
|
|
2959
|
+
* @returns {Promise<object>}
|
|
2960
|
+
*/
|
|
2961
|
+
static async resolveParams(context, overrides = {}) {
|
|
2962
|
+
const main = await super.resolveParams(context, overrides);
|
|
2963
|
+
if (!main.serviceName) {
|
|
2964
|
+
throw new ParamError(
|
|
2965
|
+
"unpause/unpauseRunner requires --serviceName (registry instance name; optional --serviceGroup, --instanceNumber, --serverName to narrow targeting)"
|
|
2966
|
+
);
|
|
2967
|
+
}
|
|
2968
|
+
return main;
|
|
2969
|
+
}
|
|
2970
|
+
async run() {
|
|
2971
|
+
return applyRunnerPaused(this.context, false);
|
|
2972
|
+
}
|
|
2973
|
+
};
|
|
2974
|
+
|
|
2975
|
+
// src/tasks/coreTasks/TaskGetLogs.js
|
|
2976
|
+
var TaskGetLogs = class extends AbstractTask {
|
|
2977
|
+
/**
|
|
2978
|
+
* @param {object} context
|
|
2979
|
+
* @param {Record<string, unknown>} [overrides]
|
|
2980
|
+
* @returns {Promise<{ source: string, resource: string, tail: number, afterTs?: string }>}
|
|
2981
|
+
*/
|
|
2982
|
+
static async resolveCustomParams(context, overrides = {}) {
|
|
2983
|
+
const merged = AbstractTask._mergeTypedParams(context, "task-get-logs", {
|
|
2984
|
+
source: "string",
|
|
2985
|
+
resource: "string",
|
|
2986
|
+
tail: "number default 100",
|
|
2987
|
+
afterTs: "string"
|
|
2988
|
+
}, overrides);
|
|
2989
|
+
const source = typeof merged.source === "string" ? merged.source.trim() : "";
|
|
2990
|
+
const resource = typeof merged.resource === "string" ? merged.resource.trim() : "";
|
|
2991
|
+
if (!source) throw new ParamError('getLogs: param "source" is required');
|
|
2992
|
+
if (!resource) throw new ParamError('getLogs: param "resource" is required');
|
|
2993
|
+
let tail = Number(merged.tail);
|
|
2994
|
+
if (!Number.isFinite(tail) || tail < 1) tail = 100;
|
|
2995
|
+
tail = Math.min(1e4, Math.max(1, Math.floor(tail)));
|
|
2996
|
+
const out = { source, resource, tail };
|
|
2997
|
+
if (typeof merged.afterTs === "string" && merged.afterTs.trim()) {
|
|
2998
|
+
out.afterTs = merged.afterTs.trim();
|
|
2999
|
+
}
|
|
3000
|
+
return out;
|
|
3001
|
+
}
|
|
3002
|
+
/**
|
|
3003
|
+
* @param {unknown} _reportProgress Unused (single-shot read, no progress events).
|
|
3004
|
+
* @returns {Promise<{ success: boolean, results: unknown }>}
|
|
3005
|
+
*/
|
|
3006
|
+
async run(_reportProgress) {
|
|
3007
|
+
const p = this.task.params ?? {};
|
|
3008
|
+
const source = String(p.source ?? "").trim();
|
|
3009
|
+
const resource = String(p.resource ?? "").trim();
|
|
3010
|
+
const tail = Math.max(1, Math.min(1e4, Number(p.tail) > 0 ? Number(p.tail) : 100));
|
|
3011
|
+
const afterTs = p.afterTs != null && String(p.afterTs).trim() ? String(p.afterTs).trim() : null;
|
|
3012
|
+
if (!source || !resource) {
|
|
3013
|
+
return {
|
|
3014
|
+
success: false,
|
|
3015
|
+
results: { error: 'getLogs requires params "source" and "resource"' }
|
|
3016
|
+
};
|
|
3017
|
+
}
|
|
3018
|
+
try {
|
|
3019
|
+
const { records, latestTs } = await readTaskIpcLogsSnapshot(this.context, {
|
|
3020
|
+
source,
|
|
3021
|
+
resource,
|
|
3022
|
+
tail,
|
|
3023
|
+
afterTs
|
|
3024
|
+
});
|
|
3025
|
+
return {
|
|
3026
|
+
success: true,
|
|
3027
|
+
results: { records, latestTs, source, resource }
|
|
3028
|
+
};
|
|
3029
|
+
} catch (e) {
|
|
3030
|
+
return {
|
|
3031
|
+
success: false,
|
|
3032
|
+
results: { error: e?.message ?? String(e) }
|
|
3033
|
+
};
|
|
3034
|
+
}
|
|
3035
|
+
}
|
|
3036
|
+
};
|
|
3037
|
+
|
|
2892
3038
|
// src/tasks/coreTasks/TaskSetRuntimeParam.js
|
|
2893
3039
|
var TaskSetRuntimeParam = class extends AbstractTask {
|
|
2894
3040
|
static defaultWaitForResult = true;
|
|
@@ -3044,7 +3190,7 @@ var TasksRegistry = class _TasksRegistry {
|
|
|
3044
3190
|
* @returns {TasksRegistry}
|
|
3045
3191
|
*/
|
|
3046
3192
|
static withCoreTasks() {
|
|
3047
|
-
return new _TasksRegistry().add("ping", TaskPing).add("sampleProcess", TaskSampleProcess).add("shellCommand", TaskShellCommand).add("systemInfo", TaskSystemInfo).add("info", TaskSystemInfo).add("taskSumAB", TaskSumAB).add("stopRunner", TaskStopRunner).add("stop", TaskStopRunner).add("getLogs", TaskGetLogs).add("setRuntimeParam", TaskSetRuntimeParam).add("setRunnerParam", TaskSetRuntimeParam);
|
|
3193
|
+
return new _TasksRegistry().add("ping", TaskPing).add("sampleProcess", TaskSampleProcess).add("shellCommand", TaskShellCommand).add("systemInfo", TaskSystemInfo).add("info", TaskSystemInfo).add("taskSumAB", TaskSumAB).add("stopRunner", TaskStopRunner).add("stop", TaskStopRunner).add("pauseRunner", TaskPauseRunner).add("pause", TaskPauseRunner).add("unpauseRunner", TaskUnpauseRunner).add("unpause", TaskUnpauseRunner).add("getLogs", TaskGetLogs).add("setRuntimeParam", TaskSetRuntimeParam).add("setRunnerParam", TaskSetRuntimeParam);
|
|
3048
3194
|
}
|
|
3049
3195
|
/**
|
|
3050
3196
|
* Register a single task class under a name. Overwrites any previous entry.
|
|
@@ -3147,6 +3293,10 @@ var SERVICE_TASK_NAMES = [
|
|
|
3147
3293
|
"ping",
|
|
3148
3294
|
"stop",
|
|
3149
3295
|
"stopRunner",
|
|
3296
|
+
"pause",
|
|
3297
|
+
"pauseRunner",
|
|
3298
|
+
"unpause",
|
|
3299
|
+
"unpauseRunner",
|
|
3150
3300
|
"shellCommand",
|
|
3151
3301
|
"systemInfo",
|
|
3152
3302
|
"info",
|
|
@@ -3608,17 +3758,25 @@ async function runTasksLoop(context, options) {
|
|
|
3608
3758
|
if (hbGroup) {
|
|
3609
3759
|
const hbIntervalMs = options.runnerHeartbeatIntervalMs ?? 1e4;
|
|
3610
3760
|
const staleMs = options.runnerHeartbeatStaleMs ?? 45e3;
|
|
3611
|
-
const
|
|
3761
|
+
const runtimeParamSpecs = mergeRuntimeParamSpecs(options.runnerRuntimeParams);
|
|
3762
|
+
context.tasksRuntimeParamSpecs = runtimeParamSpecs;
|
|
3612
3763
|
const defaultMeta = {
|
|
3613
3764
|
component: "tasks-runner",
|
|
3614
3765
|
allowedTasks: allowedTasks?.length ? allowedTasks.join(",") : "all",
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
claimJitterMs: loop0.claimJitterMs,
|
|
3619
|
-
scanLimit: loop0.scanLimit
|
|
3620
|
-
}
|
|
3766
|
+
paused: false,
|
|
3767
|
+
runtimeParams: runtimeParamSpecs,
|
|
3768
|
+
runtime: runtimeValuesForSpecs(context, runtimeParamSpecs)
|
|
3621
3769
|
};
|
|
3770
|
+
const metadata = {
|
|
3771
|
+
...defaultMeta,
|
|
3772
|
+
...options.runnerMetadata && typeof options.runnerMetadata === "object" ? options.runnerMetadata : {}
|
|
3773
|
+
};
|
|
3774
|
+
if (!Array.isArray(metadata.runtimeParams) || metadata.runtimeParams.length === 0) {
|
|
3775
|
+
metadata.runtimeParams = defaultMeta.runtimeParams;
|
|
3776
|
+
}
|
|
3777
|
+
if (!metadata.runtime || typeof metadata.runtime !== "object") {
|
|
3778
|
+
metadata.runtime = defaultMeta.runtime;
|
|
3779
|
+
}
|
|
3622
3780
|
registryReg = await registerInServicesRegistry(context, {
|
|
3623
3781
|
queueName,
|
|
3624
3782
|
target,
|
|
@@ -3628,7 +3786,7 @@ async function runTasksLoop(context, options) {
|
|
|
3628
3786
|
staleMs,
|
|
3629
3787
|
groupMaxInstances: options.runnerGroupMaxInstances,
|
|
3630
3788
|
enforceMaxInstances: options.runnerEnforceMaxInstances ?? true,
|
|
3631
|
-
metadata
|
|
3789
|
+
metadata
|
|
3632
3790
|
});
|
|
3633
3791
|
context.servicesRegistry = registryReg;
|
|
3634
3792
|
runnerIdentity = {
|
|
@@ -3678,28 +3836,38 @@ async function runTasksLoop(context, options) {
|
|
|
3678
3836
|
if (claimJitterMs > 0) {
|
|
3679
3837
|
await sleepMs(Math.floor(Math.random() * (claimJitterMs + 1)));
|
|
3680
3838
|
}
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
if (
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3839
|
+
const paused = context.tasksRuntime?.paused === true;
|
|
3840
|
+
if (!paused) {
|
|
3841
|
+
while (runningPromises.size < maxParallel) {
|
|
3842
|
+
const claimed = await claimNextRunnableTask(
|
|
3843
|
+
context,
|
|
3844
|
+
tasksTable,
|
|
3845
|
+
target,
|
|
3846
|
+
registry,
|
|
3847
|
+
scanLimit,
|
|
3848
|
+
allowedTasks,
|
|
3849
|
+
runnerIdentity
|
|
3850
|
+
);
|
|
3851
|
+
if (!claimed) break;
|
|
3852
|
+
const p = executeClaimedTask(
|
|
3853
|
+
context,
|
|
3854
|
+
tasksTable,
|
|
3855
|
+
historyTable,
|
|
3856
|
+
claimed,
|
|
3857
|
+
registry,
|
|
3858
|
+
runningTaskInstances
|
|
3859
|
+
).then(async (outcome) => {
|
|
3860
|
+
if (outcome.stopRunnerRequested && !stopRequested) {
|
|
3861
|
+
stopRequested = true;
|
|
3862
|
+
stopAllowanceMs = outcome.stopAllowanceMs || stopAllowanceMs;
|
|
3863
|
+
context.tasksRunnerStop = true;
|
|
3864
|
+
await signalRunningTasksStop(context, runningTaskInstances, stopAllowanceMs);
|
|
3865
|
+
}
|
|
3866
|
+
}).finally(() => {
|
|
3867
|
+
runningPromises.delete(p);
|
|
3868
|
+
});
|
|
3869
|
+
runningPromises.add(p);
|
|
3870
|
+
}
|
|
3703
3871
|
}
|
|
3704
3872
|
const wakePromises = [...runningPromises];
|
|
3705
3873
|
if (runningControlPromise) {
|
|
@@ -3753,16 +3921,26 @@ async function waitForTaskResult(context, taskId, options = {}) {
|
|
|
3753
3921
|
const pollMs = options.pollMs ?? 500;
|
|
3754
3922
|
const { tasksTable, historyTable } = queueToTableNames(queueName);
|
|
3755
3923
|
const deadline = Date.now() + timeoutMs;
|
|
3756
|
-
const waitStartedAt =
|
|
3757
|
-
let cachedNameOpid = null
|
|
3758
|
-
|
|
3759
|
-
|
|
3924
|
+
const waitStartedAt = new Date(Date.now() - 5e3);
|
|
3925
|
+
let cachedNameOpid = options.name != null && String(options.name).trim() !== "" ? {
|
|
3926
|
+
name: String(options.name).trim(),
|
|
3927
|
+
opid: options.opid !== void 0 ? options.opid : null
|
|
3928
|
+
} : null;
|
|
3929
|
+
async function findHistory(name, opid) {
|
|
3930
|
+
const base = () => db(historyTable).where({ name }).where("completed_at", ">=", waitStartedAt);
|
|
3931
|
+
if (opid != null && String(opid).trim() !== "") {
|
|
3932
|
+
const byOpid = await base().where({ opid }).orderBy("completed_at", "desc").first();
|
|
3933
|
+
if (byOpid) return byOpid;
|
|
3934
|
+
}
|
|
3935
|
+
const byQueueId = await base().where({ opid: taskId }).orderBy("completed_at", "desc").first();
|
|
3936
|
+
if (byQueueId) return byQueueId;
|
|
3937
|
+
const byQueueIdAny = await db(historyTable).where({ name, opid: taskId }).orderBy("completed_at", "desc").first();
|
|
3938
|
+
if (byQueueIdAny) return byQueueIdAny;
|
|
3760
3939
|
if (opid == null || opid === "") {
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
q = q.where({ opid });
|
|
3940
|
+
const byNull = await base().whereNull("opid").orderBy("completed_at", "desc").first();
|
|
3941
|
+
if (byNull) return byNull;
|
|
3764
3942
|
}
|
|
3765
|
-
return
|
|
3943
|
+
return void 0;
|
|
3766
3944
|
}
|
|
3767
3945
|
while (Date.now() <= deadline) {
|
|
3768
3946
|
const legacy = await db(historyTable).where({ id: taskId }).orderBy("created_at", "desc").first();
|
|
@@ -3772,18 +3950,17 @@ async function waitForTaskResult(context, taskId, options = {}) {
|
|
|
3772
3950
|
const pending = await db(tasksTable).where({ id: taskId }).first();
|
|
3773
3951
|
if (pending) {
|
|
3774
3952
|
cachedNameOpid = { name: pending.name, opid: pending.opid };
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
}
|
|
3779
|
-
} else if (cachedNameOpid) {
|
|
3780
|
-
const done = await historySinceWait(cachedNameOpid.name, cachedNameOpid.opid);
|
|
3953
|
+
}
|
|
3954
|
+
if (cachedNameOpid) {
|
|
3955
|
+
const done = await findHistory(cachedNameOpid.name, cachedNameOpid.opid);
|
|
3781
3956
|
if (done) {
|
|
3782
3957
|
return done;
|
|
3783
3958
|
}
|
|
3784
|
-
return null;
|
|
3785
3959
|
} else {
|
|
3786
|
-
|
|
3960
|
+
const byQueueId = await db(historyTable).where({ opid: taskId }).orderBy("completed_at", "desc").first();
|
|
3961
|
+
if (byQueueId) {
|
|
3962
|
+
return byQueueId;
|
|
3963
|
+
}
|
|
3787
3964
|
}
|
|
3788
3965
|
await sleepMs(pollMs);
|
|
3789
3966
|
}
|
|
@@ -3923,10 +4100,12 @@ var TasksManager = class _TasksManager {
|
|
|
3923
4100
|
};
|
|
3924
4101
|
export {
|
|
3925
4102
|
AbstractTask,
|
|
4103
|
+
DEFAULT_RUNTIME_PARAM_SPECS,
|
|
3926
4104
|
LOGGER_RUNTIME_KEYS,
|
|
3927
4105
|
LOOP_RUNTIME_KEYS,
|
|
3928
4106
|
SERVICE_TASK_NAMES,
|
|
3929
4107
|
TaskGetLogs,
|
|
4108
|
+
TaskPauseRunner,
|
|
3930
4109
|
TaskPing,
|
|
3931
4110
|
TaskSampleProcess,
|
|
3932
4111
|
TaskSetRuntimeParam,
|
|
@@ -3934,9 +4113,11 @@ export {
|
|
|
3934
4113
|
TaskStopRunner,
|
|
3935
4114
|
TaskSumAB,
|
|
3936
4115
|
TaskSystemInfo,
|
|
4116
|
+
TaskUnpauseRunner,
|
|
3937
4117
|
TasksManager,
|
|
3938
4118
|
TasksRegistry,
|
|
3939
4119
|
appendTaskIpcLog,
|
|
4120
|
+
applyRunnerPaused,
|
|
3940
4121
|
applyRuntimeParam,
|
|
3941
4122
|
applyRuntimePatch,
|
|
3942
4123
|
coerceRuntimeValue,
|
|
@@ -3954,6 +4135,7 @@ export {
|
|
|
3954
4135
|
listServicesRegistry,
|
|
3955
4136
|
matchesParsedPattern,
|
|
3956
4137
|
mergeAllowedTasksWithServiceTasks,
|
|
4138
|
+
mergeRuntimeParamSpecs,
|
|
3957
4139
|
nextTimeMatch,
|
|
3958
4140
|
normalizeAllowedTasks,
|
|
3959
4141
|
queueToTableNames,
|
|
@@ -3967,6 +4149,8 @@ export {
|
|
|
3967
4149
|
resolveSteps,
|
|
3968
4150
|
runNodeTaskScript,
|
|
3969
4151
|
runTasksLoop,
|
|
4152
|
+
runtimeParamSpecsFromMetadata,
|
|
4153
|
+
runtimeValuesForSpecs,
|
|
3970
4154
|
taskHistoryInsertFromQueueRow,
|
|
3971
4155
|
timeMatcher,
|
|
3972
4156
|
touchServicesRegistry as touchRunnerHeartbeat,
|