Skip to content

fix(database): Add opt-in PostgreSQL session recovery - #1

Merged
wilcorrea merged 3 commits into
mainfrom
codex/pgsql-session-recovery
Oct 29, 2026
Merged

wilcorrea merged 3 commits into
mainfrom
codex/pgsql-session-recovery

Conversation

@wilcorrea

@wilcorrea wilcorrea commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Problem and behavior

A failed Swoole PostgreSQL session can spread transport/protocol errors through the pool. Extract the connectivity fixes from QuoteGuide #318 and #320 into an explicit Serendipity opt-in module.

The nine PostgreSQL implementation classes are extracted from QuoteGuide eb75e2ad, with a subsequent classifier correction that preserves authoritative SQL diagnostics while still recognizing native transport failures with stale diagnostics. The backend remains hyperf/db with Swoole\Coroutine\PostgreSQL. Failed queries, writes, BEGIN and COMMIT are never replayed. Invalid transactions cannot reconnect; failed COMMIT confirmation remains an uncertain outcome. Native Hyperf pool counters and waiters are preserved.

Enable through ...PostgreSQLSessionRecovery::dependencies() in application dependency configuration. Installation alone changes no bindings; other drivers remain unchanged. See docs/postgresql-session-recovery.md.

Restore CI on a clean install

  • Build the development/CI image from a pinned PHP 8.3.36 base and MongoDB extension 1.21.12, verifying the extension archive checksum. Keep current security advisories active and leave library dependency constraints unchanged.
  • Correct checkout/cache ordering and cache inputs; rebuild the image during dependency installation.
  • Replace the unavailable legacy Mongo shell healthcheck with a read-only mongosh primary-readiness check.
  • Preserve mixed factory results in InputExtension while clearing cached validators/scenes for objects and isolating teardown context.
  • Preserve the original SQLSTATE-bearing exception when wrapping it in RepositoryException, passing an integer code to PHP's constructor; normalize HTTP headers according to the PSR string-array contract.
  • Remove Rector's obsolete cache API. Exercise Sentry initialization failure deterministically through its integrations callback, without relying on SDK-specific rejection of malformed options or changing production Sentry behavior.

Validation

  • Cold make setup passed with PostgreSQL 16.2 and MongoDB 6.0: migrations completed, Mongo bootstrap exited 0, all service healthchecks passed. Local overrides only isolate names, ports, network, credentials and architecture.
  • No pre-existing lockfile was used: Composer freshly resolved 214 packages in the corrected image. No platform/security bypasses or library lockfile are committed.
  • Full make ci passed: 633 tests / 1,849 assertions, including PHP-CS, PHPStan, Deptrac, PHPMD, Rector and Psalm.
  • All ten new PostgreSQL classes, InputExtension, and RepositoryException: 100% statements and methods. Header normalization's changed lines are covered.
  • actionlint and Compose configuration validation passed; independent review found no blocking defects.
  • Composer audit found no known security vulnerabilities. It still reports the two pre-existing abandoned packages (laminas/laminas-mime, opentracing/opentracing), yielding exit 2 under its default abandonment policy; this is not reported as an entirely clean audit.
  • The initial PostgreSQL extraction previously passed 62 tests / 274 assertions on the exact production base image (amd64), digest sha256:c099d1929deb41dad2d56e8c2077708ad378feed78ec84188dec9a2c8ea2df99.

QuoteGuide's consuming PR has already passed its full lint, 2,790 tests / 5,940 assertions, 80% per-class coverage gate, and 18 focused consumer tests on development and production images. It currently pins the extraction revision 970f21f; replace that development reference with the published library version before merging the consumer.

Classifier regression correction

Ordinary server SQL errors now take precedence over transport words appearing in SQL text or diagnostic details. Native driver error prefixes, nonzero driver codes and native Swoole warnings still identify current transport failure even when an old SQLSTATE remains present.

  • Regression established red on PostgreSQL 16.2: missing relation missing_onerror_review_probe invalidated a healthy session.
  • Real savepoint regression now preserves the same backend PID, nested rollback and outer writes through commit, including a relation name containing broken pipe.
  • A real client timeout with stale 42P01 and driver code zero still replaces the physical session on the next acquisition and executes the callback exactly once.
  • The classifier retains 100% statements/methods coverage; no retry paths, backend, interfaces or configuration were changed.

Remote CI

GitHub Actions run 40962391413 completed successfully on commit a6aa336: clean environment setup, all linters, 633 tests / 1,849 assertions, and SonarCloud analysis passed. No release or deployment was performed.

Actual lost COMMIT acknowledgement is not a tested transport scenario. This change does not identify the original production trigger. No PDO migration, Terraform, tracing/logging/readiness extraction, partner retries, release or deployment.

@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Caution

Review failed

The pull request is closed.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@wilcorrea
wilcorrea marked this pull request as ready for review October 29, 2026 23:08
@wilcorrea
wilcorrea merged commit f20cdfa into main Oct 29, 2026
2 checks passed
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.

1 participant