mirror of
https://github.com/block/buzz.git
synced 2026-10-27 20:41:57 +00:00
## Summary This drops the channel-TTL event trigger. The application already refreshes ephemeral-channel deadlines in the event transaction (`event_follow_up::refresh_channel_ttls`, from #8135), so the trigger only repeats that work. This PR originally retired both follow-up triggers. #8352 has since retired the push-match trigger in migration 0063, so after the rebase this PR covers only the TTL half. Migration `0065_retire_channel_ttl_trigger.sql`: - `SET LOCAL lock_timeout = '5s'` (the same bound as 0063) - drops `events_refresh_channel_ttl` and `refresh_channel_ttl_after_event_insert()` Dropping the trigger on the partitioned parent also drops its partition clones. Published migrations, including 0022 and 0024, stay checksum-frozen. The same objects are removed from `schema/` (`schema/functions/…`, `schema/triggers/events.sql`, `schema/schema.sql`) and from the pgschema reconcile script. After this, migrated and desired-state databases have no event follow-up triggers. Tests: - `follow_up_retirement_tests.rs` (renamed from `push_retirement_tests.rs`): the push-retirement upgrade test now stops at 0063. A new test upgrades 0064 → 0065 and checks that the TTL trigger is gone from the parent and every partition, that the function is gone, and that the published checksums haven't changed. - `event_follow_up_postgres_tests.rs`: the contract now has two arms. `AppOnly` is the shipped schema, where both triggers are absent. `Dual` reconstructs the historical overlap of both triggers. The `PushRetired` arm (the push trigger dropped, the TTL trigger kept) was the shipped state before this PR. Its tests are removed because `Dual` and `AppOnly` together cover it. - `embedded_migrator_contains_consolidated_initial_schema` pins the 0065 statements and checks that both objects are absent from the desired schema. **Deploy gate:** do not run 0065 against a database still served by a relay older than #8135. After 0065, raw SQL writers no longer refresh TTL deadlines. `docs/push-gateway-deployment.md` is updated to match. ### What got simpler The trigger and the app no longer both refresh TTL deadlines; the app is now the only producer. One plpgsql function and one trigger are gone from both schema paths, and 8 per-partition drops are gone from the reconcile script. The follow-up contract drops from three arms to two. ### Related issue BUZZ-313 (Linear), part of the trigger-retirement work. ### Testing Head is `4f7d0baf0`. Results below are at `678927730` unless noted. `678927730..4f7d0baf0` changes only one test in `crates/buzz-db/src/store/event.rs`, described in the first bullet. - **Fixed test, `permanent_channel_event_commits_do_not_lock_the_channel_row`** (`4f7d0baf0`). - **Why it changed:** after 0065, its raw-pool inserts no longer ran any TTL refresh, so the test passed whatever `refresh_channel_ttls` did. This was raised in review. - **What it does now:** it inserts through the production `AdmittedTx` path and keeps the barrier and the tuple-lock probe. It commits all N transactions while an external transaction holds `FOR SHARE` on the channel row. It also asserts that no `buzz_db_channel_ttl_refresh_failures_total` is counted. - **Mutation check:** with `SELECT … FOR UPDATE` injected into `refresh_channel_ttl`, the new test fails (`must not wait on the channel row`, timeout at 10s). The old test passes under the same mutation. - **Blox:** fmt and `buzz-db` clippy pass. - **GitHub CI at `4f7d0baf0`:** every required check passes (56 pass, 0 fail). CI builds the merge ref with `main` `93ffc37cb`. - **New and renamed tests, checked by name in the CI logs at `4f7d0baf0`.** These pass in PostgreSQL Domain / PostgreSQL Tests ([117033725006](https://github.com/block/buzz/actions/runs/38915998692/job/117033725006)): - `permanent_channel_event_commits_do_not_lock_the_channel_row` - `migration_schema_ttl_retirement_drops_every_partition_trigger_and_keeps_checksums` - `migration_schema_push_retirement_preserves_ttl_and_published_checksums` - `event_insert_ttl_refresh_handles_permanent_ephemeral_duplicate_and_activation_race` - `{desired,migration_schema}_event_follow_up_contract_{dual,app_only}` (four tests) `embedded_migrator_contains_consolidated_initial_schema` passes in Rust / Unit Tests ([117024125423](https://github.com/block/buzz/actions/runs/38915998692/job/117024125423)). No `*_push_retired` test runs anywhere. - **Blox gates at `678927730`** (private PG16 + Redis, on a workstation shared with other sessions): - `cargo fmt --check`, workspace `clippy -D warnings` and `buzz-db --lib` all pass. - The `buzz-admin`, `buzz-audit`, `buzz-deletion`, `buzz-push-gateway`, `buzz-search` and `buzz-workflow` Postgres packages pass. - `buzz-db`: 517 of 519 tests passed. The 2 that hung, both `writer_pool_*` tests, were killed. `buzz-relay`: 413 of 426 passed. The 13 failures are covered below. - **Uncontended reruns at `4f7d0baf0`** on a fresh, idle workstation (PG16.15, `competing=0` for every arm): - **`writer_pool_rejects_non_read_committed_database_default` predates this PR.** It timed out 3/3 at head and 3/3 at `main` `93ffc37cb`, with a 300s timeout per run. - **`writer_pool_metrics_stop_after_session_timeout_setup_failure` also predates this PR.** It timed out 2/3 at head and 2/3 at `main`, and passed in the remaining run on each side. - Both tests pass in CI. The gate accepts them as a named exception for this PR, as a pre-existing hang on the PG16 test environment. - **`buzz-db`:** 518 of 519 tests passed. The single failure is `writer_pool_rejects_non_read_committed_database_default`, killed after it hung (the exception above). - **`buzz-relay`: still open.** 413 of 426 tests passed. The same 13 `handlers::group_state_postgres_tests` failed as on the shared box, each panicking at once in its fixture's `ensure community` step with `Sqlx(PoolTimedOut)`. Contention does not explain them. The fixture's community setup is in `buzz-db`, which this PR changes. A head/`main` comparison of the full `buzz-relay` package on the same idle box is running to find out whether this predates the PR. All 13 pass in CI at this head. - **E2E (Gimli, Blox)** at `050e593af`. `050e593af..678927730` changes only tests and docs; the migration, schema and runtime code are byte-identical. Gimli's audited verdict: **EXERCISED AND WORKS**, for DB and relay runtime only. Gimli ran it at `050e593af`; this head's runtime is byte-identical but was not freshly executed. - **Upgrade:** a real relay startup took the schema from 0064 to 0065. That removed the TTL function and the trigger from the parent table and from all 8 partitions. Checksums for migrations 1–64 are unchanged. - **Lock-timeout rollback:** with a real lock held, the migration failed with `55P03` at 5.0007s and the schema rolled back fully to 64. Once the lock was released, a retry applied 65. - **Fresh desired schema:** after pgschema plus reconcile, the retired objects are absent. - **Real signed kind-9 sends:** on both schema paths, these refreshed ephemeral-channel deadlines to about +600s. Permanent channels stayed NULL. - **Raw SQL insert:** at 64 it refreshed the deadline. After 65 it left the deadline unchanged, on both the upgraded and the fresh schema. - **Not covered:** native or device testing, and deploy. - **Review:** Legolas found 0 P0 and 0 P1. His three optional P2s are fixed in `678927730`. - **No human app test:** this is a DB-only change. - **Migration numbering:** #8237 and #8372 also add a `0065_*` migration. Whichever PR merges second must renumber. --------- Signed-off-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz> Co-authored-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz>
211 lines
8.5 KiB
PL/PgSQL
211 lines
8.5 KiB
PL/PgSQL
-- Desired-state database manifest.
|
|
--
|
|
-- `tables/public/<table>.sql` declares one table per file: its CREATE TABLE
|
|
-- and the CREATE INDEX statements on it, the one-table-per-file shape SchemaBot
|
|
-- reads. `tables/` is the SchemaBot schema directory and `public` is its
|
|
-- namespace, so nothing else may live under it.
|
|
--
|
|
-- Everything SchemaBot cannot apply lives in this directory's other
|
|
-- subdirectories: `types/`, `functions/`, `partitions/`, `triggers/` (including
|
|
-- write-fence attachment), `seeds/`, and the `community_write_fence.sql`
|
|
-- bootstrap. This file composes all of them into one fresh database, in load
|
|
-- order: types → functions → tables → partitions → triggers → seeds → fence.
|
|
--
|
|
-- `./bin/pgschema apply --file schema/schema.sql` resolves the `\i` includes
|
|
-- relative to this file (it refuses `..`). `pgschema` skips INSERTs and some
|
|
-- storage parameters, so every apply caller must then run
|
|
-- `scripts/reconcile-schema-after-pgschema.sql`. Raw `psql` resolves `\i`
|
|
-- against the working directory instead, so run it from here:
|
|
-- `cd schema && psql -f schema.sql`.
|
|
--
|
|
-- Adding a table: add `tables/public/<table>.sql` and include it below after
|
|
-- the tables it references; put its partitions, triggers, and seed rows in the
|
|
-- matching subdirectories and include those too. This file holds only `\i`
|
|
-- lines and `CREATE EXTENSION`. Outside `tables/public/`, no file may create,
|
|
-- alter or drop a table or index, except `CREATE TABLE ... PARTITION OF` in
|
|
-- `partitions/`. The layout test enforces both.
|
|
|
|
-- Buzz initial Postgres schema — multi-tenant.
|
|
--
|
|
-- Source of truth for fresh database setup. This is a clean, from-scratch
|
|
-- schema in which `community_id` is a first-class, server-resolved key on
|
|
-- every tenant-scoped row. It is NOT additive over the single-community
|
|
-- schema; the rewrite replaces it. Existing single-community deployments
|
|
-- migrate via the documented backfill migration (0002), which assigns all
|
|
-- pre-existing rows to one default community.
|
|
--
|
|
-- The governing contract is docs/multi-tenant-conformance.md. Every table
|
|
-- below cites the conformance surface it implements. The invariant behind the
|
|
-- whole schema (conformance "row zero"): a request's community is resolved
|
|
-- from the connection host by the server, never supplied by the client, and
|
|
-- every scoped row carries that immutable `community_id`.
|
|
--
|
|
-- Migration-lint obligations enforced by the Lane 0 lint harness:
|
|
-- 1. Every tenant-scoped table has `community_id NOT NULL`.
|
|
-- 2. No UNIQUE / PRIMARY KEY / FK on a scoped table is observable across
|
|
-- communities: each leads with `community_id` (or, for child rows whose
|
|
-- parent already pins the community, joins carry the community tuple).
|
|
-- 3. `channels.community_id` is immutable (triggers/channels.sql; no UPDATE path).
|
|
-- 4. Operator-global tables are named in the explicit allowlist, not implied.
|
|
|
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
|
|
|
-- types
|
|
\i types/channel_type.sql
|
|
\i types/channel_visibility.sql
|
|
\i types/member_role.sql
|
|
\i types/workflow_status.sql
|
|
\i types/run_status.sql
|
|
\i types/approval_status.sql
|
|
\i types/delivery_method.sql
|
|
\i types/subscription_status.sql
|
|
\i types/pause_reason.sql
|
|
\i types/channel_add_policy.sql
|
|
|
|
-- functions
|
|
\i functions/channels_community_id_immutable.sql
|
|
\i functions/guard_channel_roster_snapshot.sql
|
|
\i functions/events_created_at_floor_guard.sql
|
|
\i functions/prevent_community_deletion_request_retargeting.sql
|
|
\i functions/prevent_community_deletion_approval_removal.sql
|
|
\i functions/protect_community_deletion_manifest_keys.sql
|
|
\i functions/community_deletion_lock_key.sql
|
|
\i functions/community_write_fence_excluded_table.sql
|
|
\i functions/community_write_allowed.sql
|
|
\i functions/assert_community_write_allowed.sql
|
|
\i functions/enforce_community_write_fence.sql
|
|
\i functions/enforce_community_tombstone.sql
|
|
\i functions/attach_community_write_fence.sql
|
|
\i functions/profile_name_fields.sql
|
|
|
|
-- tables
|
|
\i tables/public/communities.sql
|
|
\i tables/public/channels.sql
|
|
\i tables/public/channel_members.sql
|
|
\i tables/public/users.sql
|
|
\i tables/public/personal_read_accounts.sql
|
|
\i tables/public/personal_read_frontiers.sql
|
|
\i tables/public/events.sql
|
|
\i tables/public/event_mentions.sql
|
|
\i tables/public/subscriptions.sql
|
|
\i tables/public/delivery_log.sql
|
|
\i tables/public/workflows.sql
|
|
\i tables/public/workflow_runs.sql
|
|
\i tables/public/workflow_approvals.sql
|
|
\i tables/public/scheduled_workflow_fires.sql
|
|
\i tables/public/api_tokens.sql
|
|
\i tables/public/rate_limit_violations.sql
|
|
\i tables/public/thread_metadata.sql
|
|
\i tables/public/reactions.sql
|
|
\i tables/public/pubkey_allowlist.sql
|
|
\i tables/public/relay_members.sql
|
|
\i tables/public/join_policy_acceptances.sql
|
|
\i tables/public/relay_invites.sql
|
|
\i tables/public/archived_identities.sql
|
|
\i tables/public/audit_log.sql
|
|
\i tables/public/moderation_actions.sql
|
|
\i tables/public/moderation_reports.sql
|
|
\i tables/public/community_bans.sql
|
|
\i tables/public/_operator_global_tables.sql
|
|
\i tables/public/git_repo_names.sql
|
|
\i tables/public/parameterized_event_watermarks.sql
|
|
\i tables/public/product_feedback.sql
|
|
\i tables/public/push_leases.sql
|
|
\i tables/public/push_wake_outbox.sql
|
|
\i tables/public/push_match_queue.sql
|
|
\i tables/public/push_gateway_challenges.sql
|
|
\i tables/public/push_gateway_installations.sql
|
|
\i tables/public/push_gateway_delegations.sql
|
|
\i tables/public/push_gateway_endpoint_quotas.sql
|
|
\i tables/public/push_gateway_delivery_auth_replays.sql
|
|
\i tables/public/push_gateway_delivery_request_replays.sql
|
|
\i tables/public/replica_heartbeat.sql
|
|
\i tables/public/community_deletion_requests.sql
|
|
\i tables/public/community_deletion_approvals.sql
|
|
\i tables/public/community_deletion_checkpoints.sql
|
|
\i tables/public/community_deletion_manifest_keys.sql
|
|
\i tables/public/storage_taxonomy_sweeps.sql
|
|
\i tables/public/community_serving_write_leases.sql
|
|
\i tables/public/community_deletion_executor_heartbeats.sql
|
|
\i tables/public/relay_operators.sql
|
|
\i tables/public/relay_admin_actions.sql
|
|
\i tables/public/relay_admin_outbox.sql
|
|
\i tables/public/operator_listener_pubkeys.sql
|
|
\i tables/public/operator_listener_outbox.sql
|
|
\i tables/public/relay_operator_audit.sql
|
|
\i tables/public/storage_accounting_snapshots.sql
|
|
\i tables/public/artifact_heads.sql
|
|
\i tables/public/artifact_revisions.sql
|
|
|
|
-- partitions
|
|
\i partitions/events.sql
|
|
\i partitions/delivery_log.sql
|
|
|
|
-- triggers
|
|
\i triggers/channels.sql
|
|
\i triggers/events.sql
|
|
\i triggers/community_deletion_requests.sql
|
|
\i triggers/community_deletion_approvals.sql
|
|
\i triggers/community_deletion_manifest_keys.sql
|
|
\i triggers/communities.sql
|
|
\i triggers/api_tokens.sql
|
|
\i triggers/archived_identities.sql
|
|
\i triggers/audit_log.sql
|
|
\i triggers/channel_members.sql
|
|
\i triggers/community_bans.sql
|
|
\i triggers/delivery_log.sql
|
|
\i triggers/event_mentions.sql
|
|
\i triggers/git_repo_names.sql
|
|
\i triggers/join_policy_acceptances.sql
|
|
\i triggers/moderation_actions.sql
|
|
\i triggers/moderation_reports.sql
|
|
\i triggers/parameterized_event_watermarks.sql
|
|
\i triggers/personal_read_accounts.sql
|
|
\i triggers/personal_read_frontiers.sql
|
|
\i triggers/pubkey_allowlist.sql
|
|
\i triggers/push_leases.sql
|
|
\i triggers/push_match_queue.sql
|
|
\i triggers/push_wake_outbox.sql
|
|
\i triggers/reactions.sql
|
|
\i triggers/relay_invites.sql
|
|
\i triggers/relay_members.sql
|
|
\i triggers/scheduled_workflow_fires.sql
|
|
\i triggers/subscriptions.sql
|
|
\i triggers/thread_metadata.sql
|
|
\i triggers/users.sql
|
|
\i triggers/workflow_approvals.sql
|
|
\i triggers/workflow_runs.sql
|
|
\i triggers/workflows.sql
|
|
\i triggers/artifact_heads.sql
|
|
\i triggers/artifact_revisions.sql
|
|
|
|
-- seeds
|
|
\i seeds/communities.sql
|
|
\i seeds/rate_limit_violations.sql
|
|
\i seeds/_operator_global_tables.sql
|
|
\i seeds/product_feedback.sql
|
|
\i seeds/push_gateway_challenges.sql
|
|
\i seeds/push_gateway_installations.sql
|
|
\i seeds/push_gateway_delegations.sql
|
|
\i seeds/push_gateway_endpoint_quotas.sql
|
|
\i seeds/push_gateway_delivery_auth_replays.sql
|
|
\i seeds/push_gateway_delivery_request_replays.sql
|
|
\i seeds/replica_heartbeat.sql
|
|
\i seeds/community_deletion_requests.sql
|
|
\i seeds/community_deletion_approvals.sql
|
|
\i seeds/community_deletion_checkpoints.sql
|
|
\i seeds/community_deletion_manifest_keys.sql
|
|
\i seeds/storage_taxonomy_sweeps.sql
|
|
\i seeds/community_serving_write_leases.sql
|
|
\i seeds/community_deletion_executor_heartbeats.sql
|
|
\i seeds/relay_operators.sql
|
|
\i seeds/relay_admin_actions.sql
|
|
\i seeds/relay_admin_outbox.sql
|
|
\i seeds/operator_listener_pubkeys.sql
|
|
\i seeds/operator_listener_outbox.sql
|
|
\i seeds/relay_operator_audit.sql
|
|
\i seeds/storage_accounting_snapshots.sql
|
|
|
|
-- Fence any community-scoped table that lacks an explicit attach.
|
|
\i community_write_fence.sql
|