toga-ai 1.0.550 → 1.0.552
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.
|
@@ -226,6 +226,16 @@ metrics**, not the database.
|
|
|
226
226
|
## Gotchas
|
|
227
227
|
|
|
228
228
|
- Class must be **`abstract`** and methods **`public static`** or routing fails.
|
|
229
|
+
- **A JSON-object parameter arrives as `stdClass`, not `array` — type it `object|array` and
|
|
230
|
+
cast.** The dispatcher decodes `Core.CronJobs.parameters` and casts **only the top level** to
|
|
231
|
+
an array (`$parameters = (array) $message->parameters;` in `Controller/Index.php`, ~L455/692),
|
|
232
|
+
then spreads it as named args. So a **nested JSON object** value stays a PHP `stdClass`; a
|
|
233
|
+
method that declares that parameter as strict `array` throws a `TypeError`
|
|
234
|
+
(*"must be of type array, stdClass given"*) at dispatch. Declare such a parameter as
|
|
235
|
+
`object|array` and `(array)`-cast it at the top of the method. (Nested JSON **arrays** decode
|
|
236
|
+
to PHP arrays fine — only JSON **objects** become `stdClass`.) This bit
|
|
237
|
+
`_Worker_Infrastructure_CloudWatch::ElasticBeanstalkHealth`'s `environments` region-map in
|
|
238
|
+
production — see [cross-account-aws-access.md](./cross-account-aws-access.md).
|
|
229
239
|
- Webhook headers are **lowercased** by API Gateway (`X-GitHub-Event` → `x-github-event`).
|
|
230
240
|
- If the action needs a client DB, register it in `initialize()` — it runs before the method.
|
|
231
241
|
- **Worker actions do NOT auto-register `DB_CLIENT`.** The dispatcher registers only
|
|
@@ -259,6 +269,12 @@ metrics**, not the database.
|
|
|
259
269
|
commit-before-SQS transaction pattern that the worker relies on.
|
|
260
270
|
|
|
261
271
|
## Change history
|
|
272
|
+
- 2026-08-11 — Added the **nested-JSON-object → `stdClass` dispatch gotcha**: the dispatcher casts
|
|
273
|
+
only the top level of `CronJobs.parameters` to an array before spreading as named args
|
|
274
|
+
(`Controller/Index.php` ~L455/692), so a nested JSON object stays `stdClass` and a strict
|
|
275
|
+
`array` param throws a `TypeError` at dispatch — type such params `object|array` and
|
|
276
|
+
`(array)`-cast. Surfaced fixing `ElasticBeanstalkHealth`'s `environments` region-map in
|
|
277
|
+
production. (jcardinal)
|
|
262
278
|
- 2026-08-10 — Documented that **`debug_mode` changes `runTask`'s dispatch** (1 = synchronous
|
|
263
279
|
`_ApiRequest` POST to `_Config::api('worker')`, running the action inside the caller's open
|
|
264
280
|
transaction so any read-back fails; 0 = SQS enqueue), plus the debug-mode side effects
|
|
@@ -6,7 +6,7 @@ project: Worker
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-08-
|
|
9
|
+
updated: 2026-08-11
|
|
10
10
|
owners: [jcardinal]
|
|
11
11
|
files:
|
|
12
12
|
- worker2/Component/Aws/Workloads/Workloads.php
|
|
@@ -88,20 +88,49 @@ it**.
|
|
|
88
88
|
|
|
89
89
|
## First consumer — ElasticBeanstalkHealth (worked example)
|
|
90
90
|
|
|
91
|
-
`_Worker_Infrastructure_CloudWatch::ElasticBeanstalkHealth(awsAccountId,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
`
|
|
96
|
-
|
|
91
|
+
`_Worker_Infrastructure_CloudWatch::ElasticBeanstalkHealth(string $awsAccountId,
|
|
92
|
+
array $environments, string $oneuptimeUrl)` is a **parameterized cron** (args spread from
|
|
93
|
+
`Core.CronJobs.parameters` as named args) that reads each EB environment's overall health
|
|
94
|
+
through `_Component_Aws_Workloads`, maps `HealthStatus` `Degraded`/`Severe` →
|
|
95
|
+
`alarm:"HIGH"`, and pushes a **non-fatal** OneUptime heartbeat (`setLogging(false)`,
|
|
96
|
+
`setThrowExceptionsOnFailure(false)` — the Compass push pattern; see
|
|
97
97
|
[OneUptime worker2 monitoring](./oneuptime-worker2-monitoring.md)).
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
`
|
|
103
|
-
|
|
104
|
-
|
|
99
|
+
**One monitor spans multiple regions in one account.** `$environments` is a **map of
|
|
100
|
+
region → environment names** (each value an array or a comma-separated string), so a single
|
|
101
|
+
monitor can watch EB environments across different regions of the same AWS account. The old
|
|
102
|
+
flat `elasticBeanstalkEnvironmentNames` list plus a single scalar `region` argument (and the
|
|
103
|
+
`HEALTH_DEFAULT_REGION` constant) are removed — with a scalar region every environment in a
|
|
104
|
+
monitor had to share a region. The cron `parameters` JSON therefore replaces the
|
|
105
|
+
`elasticBeanstalkEnvironmentNames` + `region` keys with a single `environments` object
|
|
106
|
+
(parameters are spread as **named** args, so the JSON key must match the parameter name):
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"awsAccountId": "654654170868",
|
|
111
|
+
"environments": {
|
|
112
|
+
"us-east-1": ["env-a"],
|
|
113
|
+
"us-west-2": ["env-b"],
|
|
114
|
+
"eu-west-1": ["env-c"]
|
|
115
|
+
},
|
|
116
|
+
"oneuptimeUrl": "<push URL — credential, not stored here>"
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Credential-reuse pattern (assume once, reuse across regions):** the method calls
|
|
121
|
+
`_Component_Aws_Workloads::assumeCredentials($awsAccountId)` **once** (STS creds are
|
|
122
|
+
region-agnostic) and then constructs **one `ElasticBeanstalkClient` per region reusing those
|
|
123
|
+
same credentials** — rather than calling the per-region `client()` helper repeatedly. Prefer
|
|
124
|
+
this shape whenever one cron touches several regions of a single account: one assume-role
|
|
125
|
+
round-trip, N clients. The OneUptime payload now carries a per-environment `region` field
|
|
126
|
+
plus a top-level `regions[]` array, and the WorkerJobs summary uses `name@region=status`.
|
|
127
|
+
|
|
128
|
+
The helper adoption was captured earlier: the prior inline STS/credential code and the
|
|
129
|
+
`HEALTH_ASSUME_ROLE_NAME` / `HEALTH_ASSUME_ROLE_SESSION` constants were removed in favor of
|
|
130
|
+
`_Component_Aws_Workloads` + the `[cloud]` config keys. The prior `CheckBeanstalks()` action
|
|
131
|
+
was renamed `ElasticBeanstalkInstances()` (dbchanges2 `Core/2026-08-10c` updates the CronJobs
|
|
132
|
+
action name; `Core/2026-08-10d` seeds the parameterized `ElasticBeanstalkHealth` cron row,
|
|
133
|
+
`isActive=0`, and now carries the `environments`-map sample parameters).
|
|
105
134
|
|
|
106
135
|
## Legacy static key — being retired
|
|
107
136
|
|
|
@@ -124,8 +153,25 @@ their only home.
|
|
|
124
153
|
- Config keys are optional by design (in-code defaults), so a missing `[cloud]`
|
|
125
154
|
`workloads_role_*` key silently uses `WorkloadsRuntime` / `worker2-workloads` — set them
|
|
126
155
|
explicitly in prod ini to override.
|
|
156
|
+
- **`$environments` must be typed `object|array`, not `array`.** The cron dispatcher casts only
|
|
157
|
+
the top level of `CronJobs.parameters` to an array, so this nested JSON **object** arrives as a
|
|
158
|
+
PHP `stdClass` and a strict `array` type throws a `TypeError` at dispatch. Declare it
|
|
159
|
+
`object|array` and `(array)`-cast at the top. General rule for any object-valued cron param —
|
|
160
|
+
see [creating-worker-actions.md](./creating-worker-actions.md).
|
|
127
161
|
|
|
128
162
|
## Change history
|
|
163
|
+
- 2026-08-11 — Noted that `ElasticBeanstalkHealth`'s `$environments` must be typed `object|array`
|
|
164
|
+
(not `array`): the nested JSON object arrives as `stdClass` because the dispatcher casts only
|
|
165
|
+
the top level of `CronJobs.parameters`, so a strict `array` throws a `TypeError` at dispatch.
|
|
166
|
+
Cross-referenced the general rule in creating-worker-actions.md. (jcardinal)
|
|
167
|
+
- 2026-08-11 — `ElasticBeanstalkHealth` signature changed to
|
|
168
|
+
`(string $awsAccountId, array $environments, string $oneuptimeUrl)`: `$environments` is a
|
|
169
|
+
region → env-names map, so one monitor can watch EB environments across multiple regions
|
|
170
|
+
of one account. Removed the flat `elasticBeanstalkEnvironmentNames` list, the scalar
|
|
171
|
+
`region` arg, and the `HEALTH_DEFAULT_REGION` constant; cron `parameters` JSON now uses a
|
|
172
|
+
single `environments` object. Recorded the assume-once/reuse-credentials-across-regions
|
|
173
|
+
pattern (one `assumeCredentials()`, one `ElasticBeanstalkClient` per region) and the new
|
|
174
|
+
per-environment `region` + top-level `regions[]` payload fields. (jcardinal)
|
|
129
175
|
- 2026-08-10 — Created. Added `_Component_Aws_Workloads` as the standard cross-account AWS
|
|
130
176
|
access helper (instance-role → per-account `WorkloadsRuntime` STS assume-role), documented
|
|
131
177
|
the three-account role model and `[cloud]` config keys, and recorded that the legacy static
|
package/package.json
CHANGED