Cross-database pg_cron scheduling (restore xdist + test isolation) - #107
Merged
Conversation
Make django_absurd.pg_cron inert in tests by default so downstream projects can run pytest-xdist + standard test_ isolation without CREATE EXTENSION / cron.* breaking. State-based test-DB detection + conditional CreateExtension + gating of all 5 cron.* sites + PG_CRON_ON_TEST_DB opt-in + real-DB fail-safe check.
…aints) Captures the single-extension-per-cluster constraint, cron.database_name, cron.schedule vs schedule_in_database (target DB needs no extension — verified it schedules AND fires into an extension-less DB), the cron.job schema, and why installing django_absurd.pg_cron breaks pytest-xdist / test_ isolation. Facts verified live against pg_cron 1.6.
Reframe from the test-DB problem to a reusable understanding of pg_cron: architecture, the full scheduling API + signatures, cron.job / cron.job_run_details schemas, schedule syntax, cross-database jobs, and how to inspect a live instance. The django-absurd specifics are now a short closing note, not the focus.
…ver holds the extension)
…d + survives a test run)
…to demo, real drain in test_demo)
…tests/pg_cron, its own isolated test)
…phan pollutes future runs)
…rdown=per-test) + speed via inert gate
…grants, reconcile sketch, sweep/fixture details, change-list additions, task order)
…dated) + transition sweep (alpha, from-scratch)
…, lock, CRON_DATABASE_NAME, cleanup verbs, dup+deselected tests; add post-impl validation scenarios
…t_active / is_pg_cron_inert)
…le db-namespaced build_jobname; keep alter_job (active applies on insert only)
…X000 tolerance was dead code on the unwrapped central cursor); dedup live_database into utils.fetch_live_database
…scoped flush; drop manager+lock
…log post-commit central failure
…entral DB GUC drift must not 500 a saved row)
…_cron on ordinary test DB
…ppend, fix hint wording, assert full check message
…ime isolation test
… markers, unused param, verb-named test helpers)
…on -n4 green on the cross-DB topology)
…_init.sql; trim to CREATE EXTENSION (grants are owner no-ops, ablation-proven); fix stale example docstrings
…it.sql removed); doc updates; example mounts ./:/app
…e apps (beat/pg_cron/web) + Codecov CI matrix Runs on the cross-database pg_cron topology: the pg_cron example needs no CRON_DATABASE_NAME override (central cron.database_name=postgres; the test DB is ordinary + extension-less, scheduled cross-database). Validated: all 3 example suites pass in their own Docker stacks.
…ving Django DB fixtures) + resolve the sweep's DB alias
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #107 +/- ##
==========================================
+ Coverage 99.79% 99.83% +0.04%
==========================================
Files 122 137 +15
Lines 6211 6869 +658
Branches 216 244 +28
==========================================
+ Hits 6198 6858 +660
+ Misses 9 8 -1
+ Partials 4 3 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
…o-op branch (codecov/patch)
marcgibbons
marked this pull request as ready for review
July 27, 2026 01:15
This was referenced Jul 27, 2026
marcgibbons
added a commit
that referenced
this pull request
Jul 27, 2026
* docs: present manage.py test cleanup as intentional, drop closed-issue ref #96 closed won't-do (docs are the supported path for the non-pytest DiscoverRunner minority). Reframe the AGENTS.md + testing.md note from a 'not in this release (issue #96)' deferral into the intentional design it is. * docs(why): capture upsert-steal as the reason pg_cron jobnames are db-namespaced WHY.md framed db-namespacing as multi-tenant tidiness; the load-bearing reason is safety — pg_cron's job catalog is unique on (jobname, role) alone, so an un-namespaced schedule silently retargets an existing same-named job to a new database (a test DB could hijack a prod job). Captured from the pg_cron spec ahead of archiving it. * docs: archive shipped pg_cron cross-database spec + plan Feature shipped (#107); durable why captured in WHY.md. Both recorded in HISTORY.md with origin/main blob links (@4dde493) before removal.
marcgibbons
added a commit
that referenced
this pull request
Aug 12, 2026
* docs: drop Renovate commits from the changelog design chore(deps) is 100% dev/CI tooling under rangeStrategy update-lockfile, so the deps section and its dedupe were noise-only. * docs: keep floor changes visible, hand-fix the backfill Adds a Requirements section from the build type as a safety net Renovate cannot reach, and records that pre-#131 titles are unparsed prose needing a one-time rewrite. * docs: plan the git-cliff changelog implementation * docs: use chore for the plan's own tooling commits build is reserved for the Requirements section, which is for user-visible floor changes only. * chore(deps): add git-cliff for changelog generation * chore: configure git-cliff * docs: correct why three alpha releases render no section git-cliff omits a release whose filtered commit list is empty; tag_pattern was not the cause. * docs: fold two config corrections into the backfill task * chore: keep CI work out of the changelog * docs: generate the changelog for v0.1.0a1..a5 * fix(cliff): backfill released sections only, no Unreleased * docs: record that the changelog is released-only * docs: fill in the pre-conventional releases by hand * docs: date v0.1.0a2 from the committer timestamp * docs: attribute the README/AGENTS split to the PR that made it * docs: cut releases from the changelog * fix(cliff): stop --prepend duplicating the changelog header The header is re-rendered on every prepend and only elided when the target file matches it byte for byte; prettier had re-wrapped CHANGELOG.md's copy, so each release would have inserted a second header exactly where the release-notes slice picks up. Wrap cliff.toml's header the way prettier does, and say plainly in both copies that regeneration destroys the hand-written a2-a4 sections for good. * fix: keep the changelog PR out of the next changelog The suggested title was docs:, which cliff.toml renders — and --fill plus squash-merge turn it into a commit subject, so each release's changelog PR would come back as a Documentation bullet in the next one. Title it chore:. Also warn on the CHANGELOG.md side that its header wording and wrapping are coupled to cliff.toml's. The note lives inside the header itself: above it, it is not part of the string --prepend elides, so it would be re-emitted below the new section, inside the release-notes slice. * fix: close the gaps that lose changes from the changelog Four ways a real change could go missing, and two stale claims. - Commits git-cliff cannot parse are dropped with only a warning; the first range under this flow reaches back before the conventional-commit mandate and hides #107, runtime pg_cron work. Triage the warning in the changelog PR. - Anything merged between that PR and the cut falls in neither range, so check the gap before slicing. - GATE 2 sent a correction back through the prepend, which would stack a second copy of the same section; hand-edit the merged one instead. - revert: matched no parser and vanished. It gets its own section, because calling a revert a bug fix misreports what happened. A breaking change of a dropped type still vanishes, which config cannot fix, so it is a rule. Also drop an internal spec-retirement entry from a5, and stop claiming the hand-written sections are unrecoverable rather than unreproducible. * docs: state the no-second-prepend rule once, in step 4 Step 5 sent a missed commit back to step 4, which opens with the prepend — the move GATE 2 forbids four paragraphs later, and it stacks a duplicate section. Put the rule where the merge that triggers it happens and have both remedies name the same hand edit. Also pin the check's boundary to the most recent changelog merge, and stop it flagging ci-scoped commits, which never render. * docs: redo the whole slice step after a missed entry "Re-run this check" read as the git log line alone, so the corrected section would never be re-sliced and GATE 2 would approve — and publish — the stale notes file. Say pull, check and re-slice, matching what GATE 2 already asks for. * docs: keep the regeneration warning out of the rendered changelog The hazard is maintainer-facing; a consumer landing on the file should not read it before any release. Moved into the HTML comment, which both copies must keep byte-identical. * docs: drop the changelog tagline * test: allow CHANGELOG.md in the sdist allowlist * chore(deps): relock the examples after the git-cliff dev dep
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The app/test DB no longer holds the pg_cron extension — it's operator-managed once on a central, auto-discovered
cron.database_nameDB, and jobs schedule cross-database viaschedule_in_database. This restores pytest-xdist + standardtest_isolation and drops the--create-dbeviction hack.All
cron.*route through one seam (pg_cron/catalog.py); jobnames are db-namespaced (_dj:<db>:<source>:<name>) to keep the shared catalog safe across environments; the seam is inert under tests by default (opt-inOPTIONS["PG_CRON_ON_TEST_DB"]). MigrationCreateExtensionis dropped; fail-fast moves to E011/E012 checks.Example apps (web/beat/pg_cron) now run their own pytest suites in isolated Docker stacks.