add pgcron + scheduling primitives to Durable#75
Conversation
There was a problem hiding this comment.
💡 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".
There was a problem hiding this comment.
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_literalto fall back when input ends with$durableand added a unit test covering this delimiter-boundary edge case.
- Adjusted
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]There was a problem hiding this comment.
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.
shuyangli
left a comment
There was a problem hiding this comment.
generally lgtm minus one thing

Note
Medium Risk
Adds new database schema/migration and client methods that create/unschedule
pg_cronjobs and inject reserved headers, which can affect queue lifecycle and production Postgres configuration/permissions. CI and tests now rely on a custom Postgres image withpg_cron, so failures are more likely to be environment-related than pure logic regressions.Overview
Adds cron scheduling support via
pg_cron: newDurable::{create_schedule,list_schedules,delete_schedule}APIs plussetup_pgcron()and exported schedule types (ScheduleOptions,ScheduleInfo,ScheduleFilter).Introduces a
durable.cron_schedulesregistry table (with metadata/task indexes) and updatesdurable.drop_queue()to also unschedule/remove any cron jobs tied to a queue; includes a new SQL migration and updatessql/schema.sqlaccordingly.Updates CI to start Postgres via
docker composeusing a custom image configured forpg_cron, adds end-to-end cron tests (including verifying a cron job actually spawns tasks), and documents the new scheduling feature inREADME.md.Written by Cursor Bugbot for commit 0115d79. This will update automatically on new commits. Configure here.