@friggframework/admin-scripts 2.0.0--canary.517.559ad7e.0 → 2.0.0--canary.517.beaf080.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 +19 -1
- package/package.json +6 -6
- package/src/application/admin-script-context.js +26 -0
package/README.md
CHANGED
|
@@ -228,7 +228,7 @@ Scheduling requires `admin.enableScheduling: true` in the app definition (so the
|
|
|
228
228
|
|
|
229
229
|
## Script chaining
|
|
230
230
|
|
|
231
|
-
|
|
231
|
+
A script can enqueue follow-up scripts via `queueScript()` / `queueScriptBatch()`. Each continuation runs **asynchronously** in the executor Lambda (trigger `QUEUE`) with its `parentExecutionId` set to the queuing execution, so you can trace the lineage (and query children by `parentExecutionId`).
|
|
232
232
|
|
|
233
233
|
```javascript
|
|
234
234
|
async execute(params) {
|
|
@@ -240,6 +240,24 @@ async execute(params) {
|
|
|
240
240
|
}
|
|
241
241
|
```
|
|
242
242
|
|
|
243
|
+
### When to reach for it
|
|
244
|
+
|
|
245
|
+
Chaining is the escape hatch for work that doesn't fit a single execution. Use it to:
|
|
246
|
+
|
|
247
|
+
- **Beat the timeouts** — sync runs in the API Lambda (≈30s); async in the executor (15-min max). Split bigger jobs into children, each with its own 15-min budget.
|
|
248
|
+
- **Page / resume** — process one page, queue a continuation with the next cursor; a job of any length never hits the wall.
|
|
249
|
+
- **Fan out** — one child per item/batch runs concurrently (bounded by the queue) instead of one script grinding serially.
|
|
250
|
+
- **Isolate failures** — one bad item fails only that child's execution; siblings continue.
|
|
251
|
+
- **Stage pipelines** — script A finishes and queues script B with its output, each stage independently retried/timed.
|
|
252
|
+
|
|
253
|
+
For small, bounded, fast work — or when you need the result in the response — just use a single sync/async execution instead.
|
|
254
|
+
|
|
255
|
+
### Caveats
|
|
256
|
+
|
|
257
|
+
- **Fire-and-forget** — you don't get a child's result back; correlate via `parentExecutionId`.
|
|
258
|
+
- **At-least-once delivery** — a child may run more than once (SQS redrive on crash). **Make child scripts idempotent.**
|
|
259
|
+
- **No depth guard** — a script that queues itself fans out unbounded. Keep continuation targets terminal, or bound the chain yourself.
|
|
260
|
+
|
|
243
261
|
---
|
|
244
262
|
|
|
245
263
|
## Execution modes & reliability
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friggframework/admin-scripts",
|
|
3
3
|
"prettier": "@friggframework/prettier-config",
|
|
4
|
-
"version": "2.0.0--canary.517.
|
|
4
|
+
"version": "2.0.0--canary.517.beaf080.0",
|
|
5
5
|
"description": "Admin Script Runner for Frigg - Execute maintenance and operational scripts in hosted environments",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@aws-sdk/client-scheduler": "^3.588.0",
|
|
8
|
-
"@friggframework/core": "2.0.0--canary.517.
|
|
8
|
+
"@friggframework/core": "2.0.0--canary.517.beaf080.0",
|
|
9
9
|
"@hapi/boom": "^10.0.1",
|
|
10
10
|
"express": "^4.18.2",
|
|
11
11
|
"serverless-http": "^3.2.0"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"@friggframework/eslint-config": "2.0.0--canary.517.
|
|
15
|
-
"@friggframework/prettier-config": "2.0.0--canary.517.
|
|
16
|
-
"@friggframework/test": "2.0.0--canary.517.
|
|
14
|
+
"@friggframework/eslint-config": "2.0.0--canary.517.beaf080.0",
|
|
15
|
+
"@friggframework/prettier-config": "2.0.0--canary.517.beaf080.0",
|
|
16
|
+
"@friggframework/test": "2.0.0--canary.517.beaf080.0",
|
|
17
17
|
"eslint": "^8.22.0",
|
|
18
18
|
"jest": "^29.7.0",
|
|
19
19
|
"prettier": "^2.7.1",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"maintenance",
|
|
45
45
|
"operations"
|
|
46
46
|
],
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "beaf080b1337695f52525105e87e02c38d29b490"
|
|
48
48
|
}
|
|
@@ -57,6 +57,24 @@ class AdminScriptContext {
|
|
|
57
57
|
|
|
58
58
|
// ==================== QUEUE OPERATIONS ====================
|
|
59
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Enqueue a follow-up script as an async continuation of this execution.
|
|
62
|
+
*
|
|
63
|
+
* Fire-and-forget: the child runs later in the executor Lambda (trigger
|
|
64
|
+
* `QUEUE`) with its `parentExecutionId` set to this execution — you do NOT
|
|
65
|
+
* get the child's result back here. Use it to split work that won't fit one
|
|
66
|
+
* execution (paging past the 15-min executor timeout, per-item fan-out,
|
|
67
|
+
* multi-stage pipelines).
|
|
68
|
+
*
|
|
69
|
+
* Caveats: delivery is at-least-once, so child scripts must be idempotent;
|
|
70
|
+
* and there is no recursion/depth guard, so a script that queues itself
|
|
71
|
+
* fans out unbounded — keep continuation targets terminal or bound the chain
|
|
72
|
+
* yourself.
|
|
73
|
+
*
|
|
74
|
+
* @param {string} scriptName - Registered name of the script to enqueue
|
|
75
|
+
* @param {Object} [params={}] - Params passed to the child's execute()
|
|
76
|
+
* @throws {Error} if ADMIN_SCRIPT_QUEUE_URL is not configured
|
|
77
|
+
*/
|
|
60
78
|
async queueScript(scriptName, params = {}) {
|
|
61
79
|
const queueUrl = process.env.ADMIN_SCRIPT_QUEUE_URL;
|
|
62
80
|
if (!queueUrl) {
|
|
@@ -78,6 +96,14 @@ class AdminScriptContext {
|
|
|
78
96
|
this.log('info', `Queued continuation for ${scriptName}`, { params });
|
|
79
97
|
}
|
|
80
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Enqueue many follow-up scripts at once (batched to SQS). Same semantics
|
|
101
|
+
* and caveats as {@link queueScript} — each child runs async with this
|
|
102
|
+
* execution as its parent; make children idempotent and keep them terminal.
|
|
103
|
+
*
|
|
104
|
+
* @param {Array<{scriptName: string, params?: Object}>} entries - Scripts to enqueue
|
|
105
|
+
* @throws {Error} if ADMIN_SCRIPT_QUEUE_URL is not configured
|
|
106
|
+
*/
|
|
81
107
|
async queueScriptBatch(entries) {
|
|
82
108
|
const queueUrl = process.env.ADMIN_SCRIPT_QUEUE_URL;
|
|
83
109
|
if (!queueUrl) {
|