-
Notifications
You must be signed in to change notification settings - Fork 49
Release 4.260429.13 — hookify foundation + Mac CPU hardening sweep #1446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 23 commits
99d8597
f424d0a
e8c1c75
5c4704e
e7f580b
555855b
7c4f9d8
31b6954
2147305
e90bc51
5567e20
46172b4
b9e08d8
35b05b4
d5b9ced
f8f0201
387f9f7
0212c85
bddab56
014eb39
3b56224
fa16600
d0b834f
ef90eb5
9a490e7
ac63f90
7d4971f
8dcfcd5
41f456f
51e8654
aa67330
faa8a29
97fb712
83a687c
be8c67f
848fac1
8408da8
87d6947
59639b1
1079c7e
cffdbdf
331c1b0
af5d53f
f5d7da6
c5aa731
6ff3fbe
3c19bdf
280fe16
fa0e68e
25a54dc
a554012
492cdcf
76f9191
f2b8510
06b180a
617fe8b
e7e5b26
b84186e
b3b138d
6e67145
e8a2f5a
036b6d2
d3cb8e4
e4eefef
cfd531e
b509540
30ac991
ebf9825
c3ef841
b7ebecc
5004de5
7646ba3
6c07798
9ae0e7f
3a1da97
f043232
d56565e
275af8a
6ae003b
bb1be2d
c1dbfcd
2b26163
237d157
014dac9
a08ed45
b16dce7
3e2abf8
acadb45
8886e5f
563b3c3
e356321
20f26dc
df8ecd1
ea0f0ad
6c43aa0
079e8ea
7612a0d
a271881
b8445de
8f389ef
a40b527
eec6b8c
6ead126
2071063
64862f6
18287b5
29f9081
05d9a3a
d4bc9e0
dfc875e
785f16c
dd0d286
01348b1
cac176f
a6dd94f
7f26e60
2a90be2
139520c
f0d15a7
5d51a22
eefc9a9
bd8845e
0ae69eb
59c6514
519323f
13c8725
e0196b7
7ce9f91
0581006
8f10530
d41b353
872468b
f0533d8
0382c1b
b70e5ae
f0a1d0f
412a5ad
31a1441
882b253
47be73b
71f47be
c8f4788
b1338a9
ae27074
e171ebd
b6f08b2
aeba3e3
81b6b0d
49a6926
b5d6e8c
feb1ef2
b9b753c
2418f01
c03aeda
82b8148
4f7f113
2564fa9
3ade9ca
535d04e
ff6714f
93bba80
c5d8999
9be379f
39d076e
e83ef1a
f840cf8
09a9337
700d8e7
674049a
f8589d1
bc1f22e
f3240d1
3b1ebc4
27af634
1d8bc45
5c91365
cf96624
42fc3dc
4cc1c1b
8dd4d5f
8bb6480
a75c94e
14cbb56
9b4d8f1
c5cdb35
7624cdc
1baaf6e
bc1cc41
5658299
8836140
94e05ac
c6970b7
c6bed24
46136d8
f7538ae
3c16afb
7a94e3e
c1c9dfb
f8f479d
24b550a
1293335
ebff454
028c533
0fe08dc
c0777d2
10471d4
a47380a
9eb0537
807b02c
74a23a3
bbf0982
113b0b1
d4459c5
109c9b8
84f0634
7cd0b72
bf82263
4442008
f067427
b50734f
6cd93c5
5a5a3d5
e00b64c
4217b37
b784aa2
d385277
e0d63f8
0f37144
8b98034
242874f
c95f863
b2acaf9
785ebd5
df28469
740c018
7281e3d
b3b75d5
0e7cea7
d3378dd
26b0b70
fc615cf
afa1e29
4b3dfab
5d5ed39
0e0a189
4c8c201
c807fe4
58228e3
2624bfc
a4aad26
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| -- 054_mailbox_source_meta.sql | ||
| -- | ||
| -- Foundation for the channel-shaped envelope (PR A in the channels-pivot | ||
| -- roadmap). The mailbox row gains two optional, idempotent columns so the | ||
| -- delivery layer can carry source attribution and arbitrary metadata | ||
| -- (whatsapp phone, telegram chat id, system nudge kind, …) end-to-end: | ||
| -- | ||
| -- - `source TEXT NOT NULL DEFAULT 'agent'` — origin of the message. The | ||
| -- default keeps every pre-existing row (and every legacy `mailbox.send` | ||
| -- caller that doesn't pass an opts arg) reading as `'agent'`, which is | ||
| -- the back-compat behaviour the renderer expects (plain body, no | ||
| -- `<channel …>` wrap). | ||
| -- - `meta JSONB NOT NULL DEFAULT '{}'::jsonb` — free-form k/v map. | ||
| -- Persisted verbatim and re-hydrated by the inbox/outbox readers so | ||
| -- channel-aware UIs round-trip the data. | ||
| -- | ||
| -- Indexes are deliberately omitted — every existing inbox/outbox query | ||
| -- already filters on `to_worker` / `from_worker`, so no extra index is | ||
| -- needed for the foundation. PR C+ may add a `(to_worker, source)` index | ||
| -- once it's clear which sources warrant their own hot path. | ||
| -- | ||
| -- Re-runnable: both ALTER COLUMN clauses use `IF NOT EXISTS`. | ||
|
|
||
| ALTER TABLE mailbox | ||
| ADD COLUMN IF NOT EXISTS source TEXT NOT NULL DEFAULT 'agent'; | ||
|
|
||
| ALTER TABLE mailbox | ||
| ADD COLUMN IF NOT EXISTS meta JSONB NOT NULL DEFAULT '{}'::jsonb; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| -- 055_runtime_events_partition_drain.sql | ||
| -- Bug: genie_runtime_events_maintain_partitions never drained the DEFAULT | ||
| -- partition. Rows that landed in genie_runtime_events_default (e.g. inserts | ||
| -- after UTC midnight before the next maintenance call ran) permanently | ||
| -- blocked creation of new dated partitions, because PG validates that no | ||
| -- existing default-partition row would belong to the new partition. Symptom: | ||
| -- SQLSTATE 23514 "updated partition constraint for default partition | ||
| -- genie_runtime_events_default would be violated by some row" on every | ||
| -- subsequent `genie serve start`. Migration 038's docstring claimed the | ||
| -- nightly scheduler converted DEFAULT rows into named partitions; no such | ||
| -- code ever existed. | ||
| -- | ||
| -- Fix: | ||
| -- 1. New helper genie_runtime_events_drain_default() detaches DEFAULT, | ||
| -- ensures dated partitions exist for every day represented by its rows, | ||
| -- re-inserts the rows (parent-routing them to the correct dated | ||
| -- partition) with notify-trigger suppression, truncates the now-empty | ||
| -- detached default, and re-attaches it as DEFAULT. | ||
| -- 2. genie_runtime_events_maintain_partitions calls drain_default() before | ||
| -- creating today..today+forward_days, so a stuck DEFAULT can no longer | ||
| -- poison subsequent partition creation. | ||
| -- 3. One-shot drain at migration time so existing installs unstick on the | ||
| -- first post-upgrade `genie serve start`. | ||
|
|
||
| CREATE OR REPLACE FUNCTION genie_runtime_events_drain_default() | ||
| RETURNS INTEGER AS $$ | ||
| DECLARE | ||
| drained INTEGER := 0; | ||
| d_rec RECORD; | ||
| prev_role TEXT; | ||
| BEGIN | ||
| IF NOT EXISTS ( | ||
| SELECT 1 | ||
| FROM pg_class c | ||
| JOIN pg_namespace n ON n.oid = c.relnamespace | ||
| WHERE c.relname = 'genie_runtime_events_default' | ||
| AND n.nspname = current_schema() | ||
| ) THEN | ||
| RETURN 0; | ||
| END IF; | ||
|
|
||
| IF NOT EXISTS (SELECT 1 FROM genie_runtime_events_default LIMIT 1) THEN | ||
| RETURN 0; | ||
| END IF; | ||
|
|
||
| -- Detach so the re-insert below routes to dated partitions instead of | ||
| -- looping back into DEFAULT. Non-CONCURRENTLY form is transaction-safe. | ||
| EXECUTE 'ALTER TABLE genie_runtime_events DETACH PARTITION genie_runtime_events_default'; | ||
|
|
||
| -- Ensure a dated partition exists for every day represented in the | ||
| -- detached default. create_partition is CREATE TABLE IF NOT EXISTS, so | ||
| -- pre-existing partitions are fine. | ||
| FOR d_rec IN | ||
| SELECT DISTINCT date_trunc('day', created_at)::DATE AS d | ||
| FROM genie_runtime_events_default | ||
| LOOP | ||
| PERFORM genie_runtime_events_create_partition(d_rec.d); | ||
| END LOOP; | ||
|
|
||
| -- Suppress AFTER INSERT triggers (notify_runtime_event_split, audit chain | ||
| -- triggers, etc.) for the drain. These rows already fired their notifies | ||
| -- on their original insert; re-firing would broadcast duplicates to every | ||
| -- LISTEN'er. | ||
| prev_role := current_setting('session_replication_role'); | ||
| PERFORM set_config('session_replication_role', 'replica', true); | ||
|
|
||
|
Comment on lines
+64
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Verify how events_admin is defined and where this function is granted/called.
rg -n --iglob '*.sql' -C3 \
'CREATE ROLE events_admin|ALTER ROLE events_admin|SUPERUSER|session_replication_role|genie_runtime_events_drain_default|genie_runtime_events_maintain_partitions|GRANT EXECUTE ON FUNCTION' \
src/db/migrationsRepository: automagik-dev/genie Length of output: 10152 🌐 Web query:
💡 Result: No, a non-superuser cannot execute SET LOCAL session_replication_role = 'replica' or set_config('session_replication_role', 'replica', true) by default. Superuser privileges are required unless explicitly granted the SET privilege on this parameter. The session_replication_role parameter has a context that restricts changes to superusers and users with the appropriate SET privilege. A superuser or a user granted SET ON PARAMETER session_replication_role (via GRANT SET ON PARAMETER session_replication_role TO user;, available since PostgreSQL 15) can change it. This applies to both SET LOCAL (transaction-local) and session-level changes, as well as set_config with local=true. The parameter controls replication trigger behavior and disabling it requires these privileges for security, as setting to 'replica' skips triggers and foreign key checks. In managed services (e.g., AWS, Azure, DigitalOcean), non-superusers often cannot set it due to restrictions. Citations:
🤖 Prompt for AI Agents |
||
| EXECUTE $sql$ | ||
| INSERT INTO genie_runtime_events ( | ||
| id, repo_path, subject, kind, source, agent, team, direction, peer, | ||
| text, data, thread_id, trace_id, parent_event_id, span_id, parent_span_id, | ||
| severity, schema_version, duration_ms, dedup_key, source_subsystem, created_at | ||
| ) | ||
| OVERRIDING SYSTEM VALUE | ||
| SELECT id, repo_path, subject, kind, source, agent, team, direction, peer, | ||
| text, data, thread_id, trace_id, parent_event_id, span_id, parent_span_id, | ||
| severity, schema_version, duration_ms, dedup_key, source_subsystem, created_at | ||
| FROM genie_runtime_events_default | ||
| $sql$; | ||
|
|
||
| GET DIAGNOSTICS drained = ROW_COUNT; | ||
|
|
||
| PERFORM set_config('session_replication_role', prev_role, true); | ||
|
|
||
| EXECUTE 'TRUNCATE genie_runtime_events_default'; | ||
| EXECUTE 'ALTER TABLE genie_runtime_events ATTACH PARTITION genie_runtime_events_default DEFAULT'; | ||
|
|
||
| RETURN drained; | ||
| END; | ||
| $$ LANGUAGE plpgsql; | ||
|
|
||
| CREATE OR REPLACE FUNCTION genie_runtime_events_maintain_partitions( | ||
| forward_days INTEGER DEFAULT 2, | ||
| retention_days INTEGER DEFAULT 30 | ||
| ) | ||
| RETURNS JSONB AS $$ | ||
| DECLARE | ||
| drained INTEGER; | ||
| created INTEGER := 0; | ||
| dropped INTEGER := 0; | ||
| i INTEGER; | ||
| BEGIN | ||
| -- Drain DEFAULT first so any rows that accumulated there (UTC-midnight | ||
| -- rollover between maintenance calls) get routed to their proper dated | ||
| -- partitions before we try to CREATE the new ones. | ||
| drained := genie_runtime_events_drain_default(); | ||
|
|
||
| FOR i IN 0..forward_days LOOP | ||
| PERFORM genie_runtime_events_create_partition((CURRENT_DATE + i)::DATE); | ||
| created := created + 1; | ||
| END LOOP; | ||
| SELECT genie_runtime_events_drop_old_partitions(retention_days) INTO dropped; | ||
| RETURN jsonb_build_object( | ||
| 'created_or_present', created, | ||
| 'dropped', dropped, | ||
| 'drained_from_default', drained, | ||
| 'next_rotation_at', (CURRENT_DATE + 1)::TIMESTAMPTZ | ||
| ); | ||
| END; | ||
| $$ LANGUAGE plpgsql; | ||
|
|
||
| -- Mirror the role grants from migration 041 for the new helper. Conditional | ||
| -- so this works on installs that ran 041 before events_admin existed. | ||
| DO $$ | ||
| BEGIN | ||
| IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'events_admin') THEN | ||
| EXECUTE 'GRANT EXECUTE ON FUNCTION genie_runtime_events_drain_default() TO events_admin'; | ||
| END IF; | ||
| END$$; | ||
|
|
||
| DO $$ | ||
| DECLARE | ||
| drained INTEGER; | ||
| BEGIN | ||
| drained := genie_runtime_events_drain_default(); | ||
| IF drained > 0 THEN | ||
| RAISE NOTICE 'genie_runtime_events_default: drained % stuck row(s) into dated partitions', drained; | ||
| END IF; | ||
| END$$; | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -196,6 +196,53 @@ describe.skipIf(!DB_AVAILABLE)('Group 1 observability migrations', () => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expect(deleteErr?.message).toMatch(/append-only/); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| test('maintain_partitions drains rows stuck in DEFAULT (regression: SQLSTATE 23514)', async () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const sql = await getConnection(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Pick a far-future date that no rolling-window partition covers. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // create_partition uses session-TZ midnight, so the date string suffices. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const stuckDate = '2099-12-31'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Pre-clean any leftovers from a previous test run. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await sql`DELETE FROM genie_runtime_events WHERE kind = 'partition.drain.test'`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Insert a row whose created_at falls outside every dated partition. It | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // must route to genie_runtime_events_default. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await sql` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| INSERT INTO genie_runtime_events (repo_path, kind, source, agent, text, created_at) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| VALUES ('test', 'partition.drain.test', 'test', 'test', 'stuck', ${`${stuckDate} 12:00:00+00`}::TIMESTAMPTZ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const beforeDefault = await sql<{ n: number }[]>` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SELECT count(*)::INT AS n FROM genie_runtime_events_default | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| WHERE kind = 'partition.drain.test' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expect(beforeDefault[0].n).toBe(1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const result = await sql< | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Array<{ r: { created_or_present: number; drained_from_default: number } }> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| >`SELECT genie_runtime_events_maintain_partitions(2, 30)::jsonb AS r`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expect(result[0].r.drained_from_default).toBeGreaterThanOrEqual(1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const afterDefault = await sql<{ n: number }[]>` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SELECT count(*)::INT AS n FROM genie_runtime_events_default | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| WHERE kind = 'partition.drain.test' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expect(afterDefault[0].n).toBe(0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const inDated = await sql<{ relname: string }[]>` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SELECT tableoid::regclass::TEXT AS relname | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FROM genie_runtime_events | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| WHERE kind = 'partition.drain.test' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expect(inDated.length).toBe(1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expect(inDated[0].relname).toMatch(/genie_runtime_events_p20991231$/); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Cleanup so the dated partition created above doesn't haunt the rolling | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // window or the retention sweep on subsequent runs. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await sql`DELETE FROM genie_runtime_events WHERE kind = 'partition.drain.test'`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+206
to
+244
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guarantee cleanup even when the assertion path fails.
Proposed fix- // Insert a row whose created_at falls outside every dated partition. It
- // must route to genie_runtime_events_default.
- await sql`
- INSERT INTO genie_runtime_events (repo_path, kind, source, agent, text, created_at)
- VALUES ('test', 'partition.drain.test', 'test', 'test', 'stuck', ${`${stuckDate} 12:00:00+00`}::TIMESTAMPTZ)
- `;
+ try {
+ // Insert a row whose created_at falls outside every dated partition. It
+ // must route to genie_runtime_events_default.
+ await sql`
+ INSERT INTO genie_runtime_events (repo_path, kind, source, agent, text, created_at)
+ VALUES ('test', 'partition.drain.test', 'test', 'test', 'stuck', ${`${stuckDate} 12:00:00+00`}::TIMESTAMPTZ)
+ `;
- const beforeDefault = await sql<{ n: number }[]>`
- SELECT count(*)::INT AS n FROM genie_runtime_events_default
- WHERE kind = 'partition.drain.test'
- `;
- expect(beforeDefault[0].n).toBe(1);
+ const beforeDefault = await sql<{ n: number }[]>`
+ SELECT count(*)::INT AS n FROM genie_runtime_events_default
+ WHERE kind = 'partition.drain.test'
+ `;
+ expect(beforeDefault[0].n).toBe(1);
- const result = await sql<
- Array<{ r: { created_or_present: number; drained_from_default: number } }>
- >`SELECT genie_runtime_events_maintain_partitions(2, 30)::jsonb AS r`;
- expect(result[0].r.drained_from_default).toBeGreaterThanOrEqual(1);
+ const result = await sql<
+ Array<{ r: { created_or_present: number; drained_from_default: number } }>
+ >`SELECT genie_runtime_events_maintain_partitions(2, 30)::jsonb AS r`;
+ expect(result[0].r.drained_from_default).toBeGreaterThanOrEqual(1);
- const afterDefault = await sql<{ n: number }[]>`
- SELECT count(*)::INT AS n FROM genie_runtime_events_default
- WHERE kind = 'partition.drain.test'
- `;
- expect(afterDefault[0].n).toBe(0);
+ const afterDefault = await sql<{ n: number }[]>`
+ SELECT count(*)::INT AS n FROM genie_runtime_events_default
+ WHERE kind = 'partition.drain.test'
+ `;
+ expect(afterDefault[0].n).toBe(0);
- const inDated = await sql<{ relname: string }[]>`
- SELECT tableoid::regclass::TEXT AS relname
- FROM genie_runtime_events
- WHERE kind = 'partition.drain.test'
- `;
- expect(inDated.length).toBe(1);
- expect(inDated[0].relname).toMatch(/genie_runtime_events_p20991231$/);
-
- // Cleanup so the dated partition created above doesn't haunt the rolling
- // window or the retention sweep on subsequent runs.
- await sql`DELETE FROM genie_runtime_events WHERE kind = 'partition.drain.test'`;
+ const inDated = await sql<{ relname: string }[]>`
+ SELECT tableoid::regclass::TEXT AS relname
+ FROM genie_runtime_events
+ WHERE kind = 'partition.drain.test'
+ `;
+ expect(inDated.length).toBe(1);
+ expect(inDated[0].relname).toMatch(/genie_runtime_events_p20991231$/);
+ } finally {
+ // Cleanup so the dated partition created above doesn't haunt future runs.
+ await sql`DELETE FROM genie_runtime_events WHERE kind = 'partition.drain.test'`;
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| test('Group 1 migrations are idempotent on re-apply', async () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Re-run each migration body against the already-migrated schema and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // confirm the guarded statements are all no-ops. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.