Skip to content

Add system database migrations 126-130 for suspend mode - #666

Open
devhawk wants to merge 1 commit into
mainfrom
migrations-126-130
Open

devhawk wants to merge 1 commit into
mainfrom
migrations-126-130

Conversation

@devhawk

@devhawk devhawk commented Nov 14, 2026

Copy link
Copy Markdown
Collaborator

Adds system database migrations 126–130, the shared migrations Python 3.5.0 and TypeScript v5.5 added for suspend mode. They run at the same indexes as in every other SDK, and the DDL is Python's final form (after py#948). Java's required schema version rises to 130.

# Change
126 workflow_status.suspend_key TEXT, the topic a suspended recv waits on
127 idx_workflow_status_suspended on delay_until_epoch_ms where status = 'SUSPENDED' (online)
128 idx_workflow_status_deadline_v2 on workflow_deadline_epoch_ms, whose predicate also covers SUSPENDED (online)
129 Drops idx_workflow_status_deadline, superseded by 128 (online)
130 send_message wakes a SUSPENDED destination waiting on the message's topic

127–129 run CONCURRENTLY in autocommit on PostgreSQL and transactionally on CockroachDB, as 122–125 do. All five are additive, so 1.3 executors keep working on a migrated database.

Migration 130 drops send_message before creating it

Java's migration 14 named the function's fourth parameter idempotency_key; every other SDK names it message_id. PostgreSQL cannot rename an input parameter with CREATE OR REPLACE ("cannot change name of input parameter"), so Python's and TypeScript's form of 130 fails on a Java-created database. Java's 130 instead runs, in one transaction: DROP FUNCTION IF EXISTS send_message(TEXT, JSON, TEXT, TEXT), CREATE FUNCTION with Python's body and the parameter named message_id, and (PostgreSQL only) ALTER FUNCTION ... SET search_path = pg_catalog, pg_temp. Every database Java migrates ends up with message_id, whichever SDK created it.

Tests

MigrationManagerTest:

  • 125 → 130 starting from both parameter names (idempotency_key, and message_id recreated the Python way); checks the column, both new indexes, the v1 deadline index gone, the fourth parameter message_id, and search_path on PostgreSQL; re-running the DDL and the runner is harmless.
  • send_message wakes a SUSPENDED row with a matching suspend_key (including the null topic) and leaves a different key, a PENDING row, an unaddressed row and a null key alone; a send to a missing workflow still fails.
  • Fresh database, and upgrade from 47, reach 130 with the same schema.

Ran on PostgreSQL (MigrationManagerTest, PgSqlClientTest, WorkflowTimeoutSweepTest) and the new tests once on CockroachDB.

Release notes

  • A Java-created system database must cross migration 130 with Java 1.4, not with Python 3.5+ or TypeScript 5.5+, whose 130 fails on it. A database already stuck at 129 with "cannot change name of input parameter": run DROP FUNCTION "<schema>".send_message(text, json, text, text); and relaunch.
  • 130 recreates send_message, so it is then owned by the role that ran the migration; re-grant any EXECUTE you restricted to specific roles.
  • SQL that calls send_message with the named argument idempotency_key => ... must use message_id. Positional calls are unaffected.
  • 130's DROP has no CASCADE: an object PostgreSQL records as depending on send_message (such as a BEGIN ATOMIC SQL function) blocks the migration until it is dropped.

🤖 Generated with Claude Code

126 adds workflow_status.suspend_key, the topic a SUSPENDED recv waits
on. 127 indexes SUSPENDED rows by delay_until_epoch_ms. 128 adds
idx_workflow_status_deadline_v2, whose predicate also covers SUSPENDED,
and 129 drops the v1 deadline index it supersedes. 130 makes
send_message wake a SUSPENDED destination waiting on the message's topic.

Migration 130 drops send_message before creating it. Java's migration
14 named the fourth parameter idempotency_key while every other SDK
names it message_id, and CREATE OR REPLACE cannot rename an input
parameter. Dropping first lets 130 run on a system database created by
any SDK and leaves the parameter named message_id everywhere. The DROP,
CREATE and search_path ALTER run in one transaction.

The required schema version rises to 130.
@devhawk
devhawk requested review from kraftp, maxdml and qianl15 and a balanced review from Copilot November 14, 2026 01:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Dropping and recreating the shared send_message function affects ownership, grants, and dependencies, requiring human validation of production privileges and the Java-first cross-SDK upgrade path.

No open issues 🎉

What changed in this PR

Adds shared system database migrations 126–130 to prepare Java’s database schema for suspend mode, aligning migration indexes with the other SDKs.

Changes:

  • Adds suspend_key and suspended-workflow indexes, replacing the previous deadline index.
  • Recreates send_message to wake matching suspended receivers and standardize its fourth parameter as message_id.
  • Extends migration tests for upgrades, fresh databases, repeat execution, and message wake-up behavior.
File Description
transact/​src/​test/​java/​dev/​dbos/​transact/​migrations/​MigrationManagerTest.java Tests schema upgrades through 130 and suspended-receiver wake-up behavior.
transact/​src/​main/​java/​dev/​dbos/​transact/​migrations/​MigrationManager.java Adds migrations 126–130, including online index changes and the updated messaging function.
transact/​src/​main/​java/​dev/​dbos/​transact/​database/​dao/​WorkflowDAO.java Updates a comment to name the replacement deadline index; no runtime change.

Review effort: Balanced

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants