Skip to content

fix: enable production PostgreSQL persistence - #142

Open
franciscojavierarceo wants to merge 2 commits into
mainfrom
codex/issue-102-postgres-pool-config
Open

fix: enable production PostgreSQL persistence#142
franciscojavierarceo wants to merge 2 commits into
mainfrom
codex/issue-102-postgres-pool-config

Conversation

@franciscojavierarceo

Copy link
Copy Markdown
Collaborator

Summary

  • make the existing persistence layer work with PostgreSQL by using portable SQL, configurable pool/timeouts, and per-conversation row locking
  • preserve existing PostgreSQL data during the required INTEGER to BIGINT compatibility upgrade, while supporting read-only supervisor-managed schema validation
  • fail stored requests explicitly when persistence fails, add PostgreSQL integration coverage and CI, and document production rollout and TLS guidance

This is the PostgreSQL persistence slice of #102.

Closes #103.
Refs #102.

Test Plan

  • cargo fmt -- --check
  • cargo clippy --all-targets -- -D warnings
  • cargo test
  • uvx pre-commit run --all-files
  • TEST_POSTGRES_URL=... cargo test -p agentic-server-core --lib postgres_integer_widening_upgrade_preserves_existing_state -- --ignored --nocapture
  • TEST_POSTGRES_URL=... cargo test -p agentic-server-core --test postgres_storage_integration -- --ignored --nocapture
  • uv run --with-requirements docs/requirements.txt mkdocs build --strict (reaches the pre-existing broken docs/design/claude-code-integration.md link to ROADMAP.md)

Signed-off-by: Francisco Javier Arceo <farceo@redhat.com>
Signed-off-by: Francisco Javier Arceo <farceo@redhat.com>
"INSERT INTO responses \
(id, conversation_id, previous_response_id, history_item_ids, metadata, created_at) \
VALUES (?, ?, ?, ?, ?, ?) RETURNING *",
VALUES ($1, $2, $3, $4, $5, $6) RETURNING *",

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

this works for both postgres and sqlite, postgres rejects "?"

@maralbahari maralbahari left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the work. I left some inline comments

.map_err(|source| {
error!(error = ?source, "failed to persist response");
crate::executor::error::ExecutorError::Persistence(Box::new(source))
})

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: this line is too long, can import on top of the file use crate::executor::error{ExecutorError}

}

fn is_postgres_url(url: &str) -> bool {
url.starts_with("postgres://") || url.starts_with("postgresql://")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Parse the database URL once instead of detecting backends with starts_with.
SQLx parses the URL through url::Url, which normalizes URI schemes, while these checks are case-sensitive. A valid POSTGRESQL://... connection succeeds but bypasses every POSTGRES_* setting and after_connect, leaving statement and lock timeouts unset. SQLite has the same classification problem. The redactor also misses case variants. Introduce a validated DatabaseBackend parsed from Url::scheme() and reuse it for configuration, pool construction, diagnostics, and redaction.

let migration_result = sqlx::migrate!("./migrations")
.run(&mut *connection)
.await
.map_err(|error| sqlx::Error::Configuration(error.to_string().into()));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Converting MigrateError to error.to_string() and wrapping it as sqlx::Error::Configuration discards the source chain and means the new sqlx::Error::Migrate classification can never handle actual migrator failures. Preserve it with sqlx::Error::Migrate(Box::new(error)), or use a project error variant with #[source]

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.

Make PostgreSQL persistence production-ready

2 participants