Skip to content

add pgcron + scheduling primitives to Durable#75

Open
virajmehta wants to merge 13 commits intomainfrom
viraj/cron-in-durable
Open

add pgcron + scheduling primitives to Durable#75
virajmehta wants to merge 13 commits intomainfrom
viraj/cron-in-durable

Conversation

@virajmehta
Copy link
Member

@virajmehta virajmehta commented Feb 28, 2026

Note

Medium Risk
Adds new database schema/migration and client methods that create/unschedule pg_cron jobs and inject reserved headers, which can affect queue lifecycle and production Postgres configuration/permissions. CI and tests now rely on a custom Postgres image with pg_cron, so failures are more likely to be environment-related than pure logic regressions.

Overview
Adds cron scheduling support via pg_cron: new Durable::{create_schedule,list_schedules,delete_schedule} APIs plus setup_pgcron() and exported schedule types (ScheduleOptions, ScheduleInfo, ScheduleFilter).

Introduces a durable.cron_schedules registry table (with metadata/task indexes) and updates durable.drop_queue() to also unschedule/remove any cron jobs tied to a queue; includes a new SQL migration and updates sql/schema.sql accordingly.

Updates CI to start Postgres via docker compose using a custom image configured for pg_cron, adds end-to-end cron tests (including verifying a cron job actually spawns tasks), and documents the new scheduling feature in README.md.

Written by Cursor Bugbot for commit 0115d79. This will update automatically on new commits. Configure here.

@virajmehta virajmehta self-assigned this Feb 28, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 422b50a751

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for both issues found in the latest run.

  • ✅ Fixed: README uses "PostgreSQL" instead of "Postgres"
    • Updated the README line to use "Postgres" in the pg_cron integration description to match project convention.
  • ✅ Fixed: Dollar-quoting breaks when content ends with tag prefix
    • Adjusted pg_literal to fall back when input ends with $durable and added a unit test covering this delimiter-boundary edge case.

Create PR

Or push these changes by commenting:

@cursor push 07c4b46d0a
Preview (07c4b46d0a)
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -326,7 +326,7 @@
 
 **Key behaviors:**
 
-- **pg_cron integration** - Schedules are backed by PostgreSQL's pg_cron extension. At each tick, pg_cron inserts a task into the queue via `durable.spawn_task()`, and workers pick it up normally.
+- **pg_cron integration** - Schedules are backed by Postgres's pg_cron extension. At each tick, pg_cron inserts a task into the queue via `durable.spawn_task()`, and workers pick it up normally.
 - **Upsert semantics** - Calling `create_schedule` with an existing name updates the schedule in place.
 - **Origin tracking** - Scheduled tasks automatically receive `durable::scheduled_by` and `durable::cron` headers, so tasks can identify how they were spawned.
 - **Metadata filtering** - Attach arbitrary JSON metadata to schedules and filter with JSONB containment queries.

diff --git a/src/cron.rs b/src/cron.rs
--- a/src/cron.rs
+++ b/src/cron.rs
@@ -504,9 +504,10 @@
 // --- SQL escaping ---
 
 /// Dollar-quote a string using `$durable$` as the delimiter.
-/// Falls back to escaped single quotes if the content contains `$durable$`.
+/// Falls back to escaped single quotes if the content contains `$durable$`
+/// or ends with `$durable` (which would collide with the closing delimiter).
 fn pg_literal(s: &str) -> String {
-    if !s.contains("$durable$") {
+    if !s.contains("$durable$") && !s.ends_with("$durable") {
         format!("$durable${s}$durable$")
     } else {
         // Fallback: single-quote escaping (double up any single quotes)
@@ -725,6 +726,12 @@
         assert_eq!(pg_literal(content), "'has $durable$ and ''quotes'''");
     }
 
+    #[test]
+    fn test_pg_literal_fallback_when_content_ends_with_delimiter_prefix() {
+        let content = "test$durable";
+        assert_eq!(pg_literal(content), "'test$durable'");
+    }
+
     // --- Schedule name validation tests ---
 
     #[test]
This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

@virajmehta virajmehta assigned Aaron1011 and unassigned virajmehta Mar 1, 2026
@virajmehta virajmehta assigned shuyangli and Aaron1011 and unassigned Aaron1011 Mar 2, 2026
@shuyangli shuyangli assigned virajmehta and unassigned shuyangli Mar 2, 2026
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

@virajmehta virajmehta assigned shuyangli and unassigned virajmehta Mar 2, 2026
Copy link
Member

@shuyangli shuyangli left a comment

Choose a reason for hiding this comment

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

generally lgtm minus one thing

@shuyangli shuyangli assigned virajmehta and unassigned shuyangli Mar 2, 2026
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