gcp-job-runner 1.0.0 → 1.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/README.md
CHANGED
|
@@ -45,7 +45,7 @@ function pollExecution(options) {
|
|
|
45
45
|
onStatusChange("Running");
|
|
46
46
|
} else if (!hasReportedStarting) {
|
|
47
47
|
hasReportedStarting = true;
|
|
48
|
-
onStatusChange("Container starting...");
|
|
48
|
+
onStatusChange("Container starting... (this can take a few minutes)");
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
if (execution.completionTime) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-poller.mjs","names":[],"sources":["../../src/cloud/execution-poller.ts"],"sourcesContent":["import { consola } from \"consola\";\nimport { gcloudJson } from \"./gcloud\";\nimport type { GcloudExecution } from \"./types\";\nimport { parseExecution } from \"./types\";\n\ninterface PollOptions {\n /** Execution name (short name, e.g., \"my-job-abc123\") */\n executionName: string;\n /** GCP project ID */\n project: string;\n /** GCP region */\n region: string;\n /** Polling interval in milliseconds. Default: 5000 */\n interval?: number;\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n /** Called when a status transition is detected */\n onStatusChange?: (status: string) => void;\n}\n\ninterface PollResult {\n succeeded: boolean;\n execution: GcloudExecution;\n}\n\nconst DEFAULT_POLL_INTERVAL = 5000;\n\n/**\n * Poll a Cloud Run Job execution until it completes.\n * Returns whether the execution succeeded.\n */\nexport function pollExecution(options: PollOptions): Promise<PollResult> {\n const { executionName, project, region, signal, onStatusChange } = options;\n const interval = options.interval ?? DEFAULT_POLL_INTERVAL;\n\n let consecutiveErrors = 0;\n let hasStarted = false;\n let hasReportedStarting = false;\n\n return new Promise((resolve, reject) => {\n const check = () => {\n if (signal?.aborted) {\n reject(new DOMException(\"Polling aborted\", \"AbortError\"));\n return;\n }\n\n try {\n const response = gcloudJson([\n \"run\",\n \"jobs\",\n \"executions\",\n \"describe\",\n executionName,\n \"--project\",\n project,\n \"--region\",\n region,\n ]);\n\n consecutiveErrors = 0;\n\n const execution = parseExecution(response);\n\n if (!execution) {\n /** Retry on empty response */\n scheduleNext();\n return;\n }\n\n if (onStatusChange && !hasStarted) {\n if (execution.startTime) {\n hasStarted = true;\n onStatusChange(\"Running\");\n } else if (!hasReportedStarting) {\n hasReportedStarting = true;\n onStatusChange(\"Container starting
|
|
1
|
+
{"version":3,"file":"execution-poller.mjs","names":[],"sources":["../../src/cloud/execution-poller.ts"],"sourcesContent":["import { consola } from \"consola\";\nimport { gcloudJson } from \"./gcloud\";\nimport type { GcloudExecution } from \"./types\";\nimport { parseExecution } from \"./types\";\n\ninterface PollOptions {\n /** Execution name (short name, e.g., \"my-job-abc123\") */\n executionName: string;\n /** GCP project ID */\n project: string;\n /** GCP region */\n region: string;\n /** Polling interval in milliseconds. Default: 5000 */\n interval?: number;\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n /** Called when a status transition is detected */\n onStatusChange?: (status: string) => void;\n}\n\ninterface PollResult {\n succeeded: boolean;\n execution: GcloudExecution;\n}\n\nconst DEFAULT_POLL_INTERVAL = 5000;\n\n/**\n * Poll a Cloud Run Job execution until it completes.\n * Returns whether the execution succeeded.\n */\nexport function pollExecution(options: PollOptions): Promise<PollResult> {\n const { executionName, project, region, signal, onStatusChange } = options;\n const interval = options.interval ?? DEFAULT_POLL_INTERVAL;\n\n let consecutiveErrors = 0;\n let hasStarted = false;\n let hasReportedStarting = false;\n\n return new Promise((resolve, reject) => {\n const check = () => {\n if (signal?.aborted) {\n reject(new DOMException(\"Polling aborted\", \"AbortError\"));\n return;\n }\n\n try {\n const response = gcloudJson([\n \"run\",\n \"jobs\",\n \"executions\",\n \"describe\",\n executionName,\n \"--project\",\n project,\n \"--region\",\n region,\n ]);\n\n consecutiveErrors = 0;\n\n const execution = parseExecution(response);\n\n if (!execution) {\n /** Retry on empty response */\n scheduleNext();\n return;\n }\n\n if (onStatusChange && !hasStarted) {\n if (execution.startTime) {\n hasStarted = true;\n onStatusChange(\"Running\");\n } else if (!hasReportedStarting) {\n hasReportedStarting = true;\n onStatusChange(\n \"Container starting... (this can take a few minutes)\",\n );\n }\n }\n\n if (execution.completionTime) {\n const succeeded = (execution.succeededCount ?? 0) > 0;\n resolve({ succeeded, execution });\n return;\n }\n\n const completedCondition = execution.conditions?.find(\n (c) => c.type === \"Completed\",\n );\n\n if (completedCondition?.state === \"CONDITION_SUCCEEDED\") {\n resolve({ succeeded: true, execution });\n return;\n }\n\n if (completedCondition?.state === \"CONDITION_FAILED\") {\n resolve({ succeeded: false, execution });\n return;\n }\n\n scheduleNext();\n } catch (error) {\n consecutiveErrors++;\n\n if (consecutiveErrors <= 3) {\n consola.warn(\n `Failed to check execution status (attempt ${consecutiveErrors})`,\n error instanceof Error ? error.message : String(error),\n );\n }\n\n if (consecutiveErrors >= 10) {\n reject(\n new Error(\n `Polling failed after ${consecutiveErrors} consecutive errors`,\n ),\n );\n return;\n }\n\n scheduleNext();\n }\n };\n\n const scheduleNext = () => {\n setTimeout(check, interval);\n };\n\n /** Start first check after a short delay to give the execution time to register */\n setTimeout(check, interval);\n });\n}\n"],"mappings":";;;;;AAyBA,MAAM,wBAAwB;;;;;AAM9B,SAAgB,cAAc,SAA2C;CACvE,MAAM,EAAE,eAAe,SAAS,QAAQ,QAAQ,mBAAmB;CACnE,MAAM,WAAW,QAAQ,YAAY;CAErC,IAAI,oBAAoB;CACxB,IAAI,aAAa;CACjB,IAAI,sBAAsB;AAE1B,QAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,cAAc;AAClB,OAAI,QAAQ,SAAS;AACnB,WAAO,IAAI,aAAa,mBAAmB,aAAa,CAAC;AACzD;;AAGF,OAAI;IACF,MAAM,WAAW,WAAW;KAC1B;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACD,CAAC;AAEF,wBAAoB;IAEpB,MAAM,YAAY,eAAe,SAAS;AAE1C,QAAI,CAAC,WAAW;;AAEd,mBAAc;AACd;;AAGF,QAAI,kBAAkB,CAAC,YACrB;SAAI,UAAU,WAAW;AACvB,mBAAa;AACb,qBAAe,UAAU;gBAChB,CAAC,qBAAqB;AAC/B,4BAAsB;AACtB,qBACE,sDACD;;;AAIL,QAAI,UAAU,gBAAgB;AAE5B,aAAQ;MAAE,YADS,UAAU,kBAAkB,KAAK;MAC/B;MAAW,CAAC;AACjC;;IAGF,MAAM,qBAAqB,UAAU,YAAY,MAC9C,MAAM,EAAE,SAAS,YACnB;AAED,QAAI,oBAAoB,UAAU,uBAAuB;AACvD,aAAQ;MAAE,WAAW;MAAM;MAAW,CAAC;AACvC;;AAGF,QAAI,oBAAoB,UAAU,oBAAoB;AACpD,aAAQ;MAAE,WAAW;MAAO;MAAW,CAAC;AACxC;;AAGF,kBAAc;YACP,OAAO;AACd;AAEA,QAAI,qBAAqB,EACvB,SAAQ,KACN,6CAA6C,kBAAkB,IAC/D,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CACvD;AAGH,QAAI,qBAAqB,IAAI;AAC3B,4BACE,IAAI,MACF,wBAAwB,kBAAkB,qBAC3C,CACF;AACD;;AAGF,kBAAc;;;EAIlB,MAAM,qBAAqB;AACzB,cAAW,OAAO,SAAS;;;AAI7B,aAAW,OAAO,SAAS;GAC3B"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gcp-job-runner",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Run schema-driven Cloud Run jobs seamlessly in any environment",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -73,7 +73,9 @@ export function pollExecution(options: PollOptions): Promise<PollResult> {
|
|
|
73
73
|
onStatusChange("Running");
|
|
74
74
|
} else if (!hasReportedStarting) {
|
|
75
75
|
hasReportedStarting = true;
|
|
76
|
-
onStatusChange(
|
|
76
|
+
onStatusChange(
|
|
77
|
+
"Container starting... (this can take a few minutes)",
|
|
78
|
+
);
|
|
77
79
|
}
|
|
78
80
|
}
|
|
79
81
|
|