Add Postgres database#863
Conversation
|
👋 Thanks for assigning @Camillarhi as a reviewer! |
tnull
left a comment
There was a problem hiding this comment.
Took a first high-level look.
Also gates sqlite behind a feature flag, since most tests relied on this, we ended up needing to gate a lot of them behind the flag. Curious on thoughts on how to handle this best
Not sure I'm following? Why do we want to feature-gate tests based on SQLite?
Also tagging @tankyleo as a secondary reviewer here as he has a lot of recent experience with Postgres on VSS Server.
|
|
||
| // An internal runtime we use to avoid any deadlocks we could hit when waiting on async | ||
| // operations to finish from a sync context. | ||
| internal_runtime: Option<tokio::runtime::Runtime>, |
There was a problem hiding this comment.
I think we could avoid using an internal runtime for this and rather just reuse crate::runtime::Runtime, if we wanted. Though, when upstreaming to LDK we'll need to rethink all of this anyways (cf. VssStore upstreaming PR).
There was a problem hiding this comment.
Yeah I just copied VSS to be safe.
There was a problem hiding this comment.
Yeah, let's drop the extra runtime then.
There was a problem hiding this comment.
This seems to be unaddressed? (cc @benthecarman). Or I guess you interpreted 'then' as 'when we upstream'? IMO it's likely unnecessary in this case, so might as well do it now, but let me know if you'd rather keep it for now.
There was a problem hiding this comment.
Ohh missed your other comment, fixed
|
|
||
| /// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options | ||
| /// previously configured. | ||
| #[cfg(feature = "sqlite")] |
There was a problem hiding this comment.
Why do we suddenly introduce features? We so far held off and meant to do that in a dedicated PR at some point for this or next release. Is it necessary to make Postgres work?
There was a problem hiding this comment.
okay removed for now
There was a problem hiding this comment.
Seems the postgres feature is still present in the current version?
b5d297e to
e8f478b
Compare
|
Did fixes in follow up commits for ease of review. |
|
🔔 1st Reminder Hey @tankyleo! This PR has been waiting for your review. |
|
🔔 2nd Reminder Hey @tankyleo! This PR has been waiting for your review. |
tankyleo
left a comment
There was a problem hiding this comment.
Verbose review, please dismiss aggressively :)
|
@tankyleo addressed most of your comments. Lots of docs improvements. Better handling around the db name and creating the db. And did the code clean ups + test improvements you suggested. |
a8589ea to
a43b13b
Compare
|
🔔 1st Reminder Hey @tankyleo! This PR has been waiting for your review. |
|
🔔 2nd Reminder Hey @tankyleo! This PR has been waiting for your review. |
3bb9810 to
437f11f
Compare
tankyleo
left a comment
There was a problem hiding this comment.
two small nits thank you
fixed |
|
🔔 1st Reminder Hey @tnull! This PR has been waiting for your review. |
|
🔔 2nd Reminder Hey @tnull! This PR has been waiting for your review. |
|
@benthecarman Any update here? |
85652a1 to
f81b8a0
Compare
|
Responded to review |
| /// Round-robin (rather than `tokio::select!` over all slot locks) is preferred so [`POOL_SIZE`] | ||
| /// can be `cfg`-conditional without rewriting select arms. The trade-off: under contention the | ||
| /// fallback `lock().await` may park on a busy slot while another frees up a moment later. |
There was a problem hiding this comment.
Hmm not sure it's worth dropping the tokio::select to help the tests ? You probably saw this I pass --test-threads 1 over at VSS when running tests to avoid flooding connections like you mention above. But perhaps there's a better path that doesn't require passing this flag (including maybe sticking to what you have here your call).
There was a problem hiding this comment.
Switched to be a select, just have a smaller one for tests
| kv_table_name, | ||
| tls_config, | ||
| ) | ||
| .map_err(|_| BuildError::KVStoreSetupFailed)?; |
There was a problem hiding this comment.
Can we log the error returned here, like what I do in #893 ?
There was a problem hiding this comment.
that needs build_with_store_and_logger. Maybe just need to have one of these depend on the other
There was a problem hiding this comment.
Landed #893, please rebase to use build_with_store_and_logger.
|
|
||
| // An internal runtime we use to avoid any deadlocks we could hit when waiting on async | ||
| // operations to finish from a sync context. | ||
| internal_runtime: Option<tokio::runtime::Runtime>, |
There was a problem hiding this comment.
This seems to be unaddressed? (cc @benthecarman). Or I guess you interpreted 'then' as 'when we upstream'? IMO it's likely unnecessary in this case, so might as well do it now, but let me know if you'd rather keep it for now.
| /// `"postgres://user:password@localhost/ldk_db"`. | ||
| /// | ||
| /// The given `db_name` will be used or default to [`DEFAULT_DB_NAME`]. The | ||
| /// `connection_string` must not include a `dbname` when `db_name` is set, providing both |
There was a problem hiding this comment.
I believe in VSS Server we discovered that different providers have different names for default databases, and we'll need to connect to the default database to be able to initialize the configured database if it's not pre-existing. It seems we might need to add the same config option for 'default db' here, too, which will only be used for the initial connection? Or do we see a better option (given this is a quite ugly/confusing API)?
There was a problem hiding this comment.
@tankyleo discussed this and thought it might be better to punt on it for now. You can always just use whatever bespoke default db they use as your db instead of the DEFAULT_DB_NAME in your connection string. But yeah can add if you think it'll cause issues
| /// TLS configuration for PostgreSQL connections. | ||
| #[cfg(any(feature = "postgres", feature = "uniffi"))] | ||
| #[derive(Debug, Clone)] | ||
| pub struct PostgresTlsConfig { |
There was a problem hiding this comment.
This doesn't belong into this file but should be part of the postgres_store sub-module or if we deem it part of the user-facing builder API, it should be in builder.rs.
There was a problem hiding this comment.
Put it here so the bindings had access to it. Was unsure if we wanted to have the bindings require postgres enabled or not. Currently its behind the feature flag but we still need the type exposed
| /// | ||
| /// If `tls_config` is `Some`, TLS will be used for database connections. A custom CA | ||
| /// certificate can be provided via | ||
| /// [`PostgresTlsConfig::certificate_pem`](io::postgres_store::PostgresTlsConfig::certificate_pem), |
There was a problem hiding this comment.
Given the PostgresTlsConfig currently only holds one field, should certificate_pem just be an optional field directly on build_with_postgres_store? And then we could use PostgresTlsConfig internally only for now?
There was a problem hiding this comment.
yeah this solves the bindings issue above too
Add a PostgresStore implementation behind the "postgres" feature flag, mirroring the existing SqliteStore. Uses tokio-postgres (async-native) with an internal tokio runtime for the sync KVStoreSync trait, following the VssStore pattern. Includes unit tests, integration tests (channel full cycle and node restart), and a CI workflow that runs both against a PostgreSQL service container. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
🔔 1st Reminder Hey @Camillarhi! This PR has been waiting for your review. |
Add a PostgresStore implementation behind the
postgresfeature flag, mirroring the existingSqliteStore. Usestokio-postgres(async-native) with an internal tokio runtime for the syncKVStoreSynctrait, following theVssStorepattern.Also gates sqlite behind a feature flag, since most tests relied on this, we ended up needing to gate a lot of them behind the flag. Curious on thoughts on how to handle this best