Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
1443731
draft: using db-pool form a 2021 branch
momentary-lapse Jul 4, 2025
55d010d
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Jul 11, 2025
91613fb
fix
momentary-lapse Jul 11, 2025
618f635
some renaming
momentary-lapse Jul 11, 2025
ef155c5
reusable pool integrated except everywhere, some tests adapted
momentary-lapse Jul 14, 2025
f949aea
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Jul 14, 2025
6b13d21
generic pool in context and stat modules, now it compiles
momentary-lapse Jul 15, 2025
8528a7f
Merge branch 'main' into parallel-db-tests
momentary-lapse Jul 15, 2025
e90c8be
fix taplo
momentary-lapse Jul 16, 2025
5d6fe0c
clippy fix
momentary-lapse Jul 16, 2025
906c36a
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Jul 19, 2025
418e91b
clippy fix
momentary-lapse Jul 19, 2025
fe3305b
fmt fix
momentary-lapse Jul 20, 2025
a95ad45
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Jul 23, 2025
4377da8
shear fix
momentary-lapse Jul 23, 2025
e18c7f7
clippy + shear fixes
momentary-lapse Jul 23, 2025
5264ab1
fmt fix
momentary-lapse Jul 23, 2025
9db404d
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Jul 27, 2025
6e795ea
fix merge issues
momentary-lapse Jul 27, 2025
603efb3
config forrunning new tests locally
momentary-lapse Jul 27, 2025
0d59fcf
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Aug 7, 2025
1fbe5f4
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Aug 11, 2025
64bc9e6
removing the rest of serial tests
momentary-lapse Aug 12, 2025
6534cbc
fmt
momentary-lapse Aug 12, 2025
12037df
excluding serial_test dep
momentary-lapse Aug 12, 2025
b8c2836
fix
momentary-lapse Aug 13, 2025
aadfcca
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Aug 15, 2025
99f4f03
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Aug 24, 2025
2b1776b
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Sep 13, 2025
3abdada
add tokio-shared-rt library
momentary-lapse Oct 13, 2025
7457486
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Oct 13, 2025
355e6fe
updated lock
momentary-lapse Oct 13, 2025
f936ec3
removing serial
momentary-lapse Oct 14, 2025
9ab549a
post crate changes partial
momentary-lapse Oct 14, 2025
5f00b50
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Nov 3, 2025
5ba2328
merge fixes
momentary-lapse Nov 3, 2025
8f9d819
full access to r schema in tests
momentary-lapse Nov 3, 2025
738c71c
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Nov 15, 2025
1d3c3d8
made it compile
momentary-lapse Nov 15, 2025
35ac090
using db-pool version with superuser test user
momentary-lapse Nov 16, 2025
7e92da6
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Dec 6, 2025
5d52b36
PrivilegedPostgresConfig adapted to conn string containing options
momentary-lapse Dec 9, 2025
59dbc62
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Dec 15, 2025
3d469ef
tests are compiling
momentary-lapse Dec 15, 2025
7984f6d
shared runtime in tests
momentary-lapse Dec 15, 2025
f912ecf
prettier fix
momentary-lapse Dec 15, 2025
20e9b46
linter fixes
momentary-lapse Dec 15, 2025
c4ad852
removing empty file
momentary-lapse Dec 15, 2025
c7f9151
fixing tests
momentary-lapse Dec 15, 2025
90c6152
ignoring tokio to satisfy shear
momentary-lapse Dec 15, 2025
a847d44
taplo fix
momentary-lapse Dec 15, 2025
4be9c32
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Jan 1, 2026
75d5671
fixing tests and tomls
momentary-lapse Jan 1, 2026
ec18a6b
fixing lemmy_db_views_post tests
momentary-lapse Jan 2, 2026
d5b3fd5
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Jan 12, 2026
ae6ac4b
fix test
momentary-lapse Jan 12, 2026
c26ab70
some more fixes
momentary-lapse Jan 12, 2026
b9d1b18
Merge branch 'main' of github.com:LemmyNet/lemmy into parallel-db-tests
momentary-lapse Jan 24, 2026
4abcc9d
using improved db-pool config accepting a connection string
momentary-lapse Jan 24, 2026
d977c4e
Merge branch 'main' of https://github.com/LemmyNet/lemmy into paralle…
momentary-lapse Feb 11, 2026
1c1433a
Cargo lock changed
momentary-lapse Mar 1, 2026
290f64f
Merge branch 'main' of https://github.com/LemmyNet/lemmy into paralle…
momentary-lapse Mar 1, 2026
bc61f54
fixes for submodule
Mar 1, 2026
7824a91
test fix
Mar 1, 2026
9006d18
fmt fix
Mar 1, 2026
a011e9f
fix compilation
Mar 8, 2026
909c7b9
failed tests ignored
Mar 8, 2026
bfd799a
Merge branch 'main' of https://github.com/LemmyNet/lemmy into paralle…
Mar 8, 2026
21156df
removing serial in new tests
Mar 8, 2026
94ed7b2
removing empty file
Mar 8, 2026
0b4676f
removing empty file
Mar 8, 2026
b172cdb
adding multi-thread flavor
Mar 8, 2026
eba169d
db-pool upd
Mar 8, 2026
9fd3d24
Revert "db-pool upd"
Mar 8, 2026
e037df5
fix pool sizes
Mar 9, 2026
a5d4d96
Merge branch 'main' of https://github.com/LemmyNet/lemmy into paralle…
Mar 9, 2026
923177b
db-pool doesn't throw errors on cleanup
Mar 9, 2026
0230818
use serial for workers which share the same port
Mar 10, 2026
73aad3e
removing ignore
Mar 10, 2026
3b187a8
removing ignore
Mar 10, 2026
dc3c087
clippy and fmt fixes
Mar 10, 2026
9c00d0a
Merge branch 'main' of https://github.com/LemmyNet/lemmy into paralle…
Mar 31, 2026
5dfa1df
db-pool dependency library supports diesel-async 0.8.0
Mar 31, 2026
1bcd4ff
test fixes
Mar 31, 2026
28d869e
Merge branch 'main' of https://github.com/LemmyNet/lemmy into paralle…
Apr 6, 2026
46f2d66
fmt fix
Apr 6, 2026
fabeac1
Merge branch 'main' of https://github.com/LemmyNet/lemmy into paralle…
Apr 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ lemmy_db_views_vote = { version = "=1.0.0-alpha.5", path = "./crates/db_views/vo
activitypub_federation = { version = "0.7.0-beta.4", default-features = false, features = [
"actix-web",
] }
diesel = { version = "2.2.10", features = [
diesel = { version = "2.2.11", features = [
"chrono",
"postgres",
"serde_json",
Expand Down
2 changes: 1 addition & 1 deletion crates/api/api_utils/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl LemmyContext {
#[allow(clippy::expect_used)]
pub async fn init_test_federation_config() -> FederationConfig<LemmyContext> {
// call this to run migrations
let pool = build_db_pool_for_tests();
let pool = build_db_pool_for_tests().await;

let client = client_builder(&SETTINGS).build().expect("build client");

Expand Down
2 changes: 2 additions & 0 deletions crates/db_schema/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ diesel-derive-newtype = { workspace = true, optional = true }
diesel-async = { workspace = true, features = [
"deadpool",
"postgres",
"async-connection-wrapper",
], optional = true }
regex = { workspace = true, optional = true }
diesel_ltree = { workspace = true, optional = true }
Expand All @@ -73,6 +74,7 @@ i-love-jesus = { workspace = true, optional = true }
derive-new.workspace = true
tuplex = { workspace = true, optional = true }
moka = { workspace = true, optional = true }
db-pool = { git = "https://github.com/momentary-lapse/db-pool.git", branch = "edition2021", features = ["diesel-async-postgres", "diesel-async-deadpool"] }


[dev-dependencies]
Expand Down
54 changes: 52 additions & 2 deletions crates/db_schema/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ pub mod uplete;

use crate::newtypes::DbUrl;
use chrono::TimeDelta;
use db_pool::{
r#async::{
DatabasePool, DatabasePoolBuilderTrait, DieselAsyncPostgresBackend, DieselDeadpool,
},
PrivilegedPostgresConfig,
};
use deadpool::Runtime;
use diesel::{
dsl,
Expand All @@ -21,6 +27,7 @@ use diesel::{
IntoSql,
};
use diesel_async::{
async_connection_wrapper::AsyncConnectionWrapper,
pg::AsyncPgConnection,
pooled_connection::{
deadpool::{Hook, HookError, Object as PooledConnection, Pool},
Expand Down Expand Up @@ -57,6 +64,7 @@ use std::{
sync::{Arc, LazyLock, OnceLock},
time::Duration,
};
use tokio::sync::OnceCell;
use tracing::error;
use url::Url;

Expand Down Expand Up @@ -518,8 +526,50 @@ pub fn build_db_pool() -> LemmyResult<ActualDbPool> {
}

#[allow(clippy::expect_used)]
pub fn build_db_pool_for_tests() -> ActualDbPool {
build_db_pool().expect("db pool missing")
pub async fn build_db_pool_for_tests() -> ActualDbPool {
static POOL: OnceCell<DatabasePool<DieselAsyncPostgresBackend<DieselDeadpool>>> =
OnceCell::const_new();
let db_pool = POOL
.get_or_init(|| async {
let conn_string = SETTINGS.get_database_url();

let db_url = Url::parse(conn_string.as_str()).unwrap();

let config = PrivilegedPostgresConfig::new()
.host(db_url.host().unwrap().to_string())
.port(db_url.port().unwrap())
.username(db_url.username().to_string())
.password(Some(db_url.password().unwrap().to_string()));

let backend = DieselAsyncPostgresBackend::new(
config,
|manager| Pool::builder(manager).max_size(SETTINGS.database.pool_size),
|manager| Pool::builder(manager).max_size(2),
None,
move |conn| {
Box::pin(async {
let async_wrapper: AsyncConnectionWrapper<AsyncPgConnection> =
AsyncConnectionWrapper::from(conn);

schema_setup::run_with_connection(
schema_setup::Options::default().run(),
async_wrapper,
)
.expect("run migrations");

None
})
},
)
.await
.unwrap();

backend.create_database_pool().await.unwrap()
})
.await;

// TODO make compatible with ActualDbPool
db_pool.pull_immutable().await
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I created this WIP PR to share the progress and the issue I'm stuck with currently. The crate I use operates with its own structure wrapping connection pools: code
And we have our own ActualDbPool. They are kinda same, but it's not obvious for me how to correctly convert one to another.
I had an idea to make ActualDbPool a enum with two possible values: RegularPool and ReusablePool, but stuck on trying to adapt stuff like LemmyContext, which also requires pool struct to be clone-able (and ReusablePool is not). And it seems a lot of changes to the main codebase for purely test changes.
Do you folks have any ideas how to manage that? Or should I stick to the initial plan without using this library?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Our ActualDbPool is just a type alias for deadpool Pool<AsyncPgConnection>.

Their crate should be able to work with deadpool pools, but I'm not familiar with how to plug that into their crate... you'll have to ask them.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I see. I returned to this issue today after a week of a break. I'm in contact with the db-pool author and they're helping to understand a lot of moments and really willing to collaborate, so i think we'll make this work.

I'd like to clarify one moment: do we want build_db_pool_for_tests to return still ActualDbPool? db-pool has its own wrapper ReusableConnectionPool which works like a deadpool Pool, but a bit different and needs adaptation. And it might be easier to adapt tests for working with ReusableConnectionPool than converting ReusableConnectionPool to ActualDbPool

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.

The return type of build_db_pool_for_tests may be changed. Also, a DbPool variant may be added if needed.

}

#[allow(clippy::expect_used)]
Expand Down
55 changes: 39 additions & 16 deletions crates/db_schema_file/src/schema_setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::schema::previously_run_sql;
use anyhow::{anyhow, Context};
use chrono::TimeDelta;
use diesel::{
connection::SimpleConnection,
dsl::exists,
migration::{Migration, MigrationVersion},
pg::Pg,
Expand All @@ -20,6 +19,7 @@ use diesel::{
use diesel_migrations::MigrationHarness;
use lemmy_utils::{error::LemmyResult, settings::SETTINGS};
use std::time::Instant;
use diesel::connection::LoadConnection;
use tracing::debug;

diesel::table! {
Expand Down Expand Up @@ -48,14 +48,20 @@ fn replaceable_schema() -> String {

const REPLACEABLE_SCHEMA_PATH: &str = "crates/db_schema/replaceable_schema";

struct MigrationHarnessWrapper<'a> {
conn: &'a mut PgConnection,
struct MigrationHarnessWrapper<'a, Conn>
where
Conn: MigrationHarness<Pg>,
{
conn: &'a mut Conn,
#[cfg(test)]
enable_diff_check: bool,
options: &'a Options,
}

impl MigrationHarnessWrapper<'_> {
impl<Conn> MigrationHarnessWrapper<'_, Conn>
where
Conn: MigrationHarness<Pg>,
{
fn run_migration_inner(
&mut self,
migration: &dyn Migration<Pg>,
Expand All @@ -74,7 +80,10 @@ impl MigrationHarnessWrapper<'_> {
}
}

impl MigrationHarness<Pg> for MigrationHarnessWrapper<'_> {
impl<Conn> MigrationHarness<Pg> for MigrationHarnessWrapper<'_, Conn>
where
Conn: MigrationHarness<Pg>,
{
fn run_migration(
&mut self,
migration: &dyn Migration<Pg>,
Expand Down Expand Up @@ -178,12 +187,10 @@ pub enum Branch {
ReplaceableSchemaNotRebuilt,
}

pub fn run(options: Options) -> LemmyResult<Branch> {
let db_url = SETTINGS.get_database_url();

// Migrations don't support async connection, and this function doesn't need to be async
let mut conn = PgConnection::establish(&db_url)?;

pub fn run_with_connection<Conn>(options: Options, mut conn: Conn) -> LemmyResult<Branch>
where
Conn: Connection<Backend = Pg> + MigrationHarness<Pg> + LoadConnection,
{
// If possible, skip getting a lock and recreating the "r" schema, so
// lemmy_server processes in a horizontally scaled setup can start without causing locks
if !options.revert
Expand Down Expand Up @@ -250,7 +257,17 @@ pub fn run(options: Options) -> LemmyResult<Branch> {
Ok(output)
}

fn run_replaceable_schema(conn: &mut PgConnection) -> LemmyResult<()> {
pub fn run(options: Options) -> LemmyResult<Branch> {
let db_url = SETTINGS.get_database_url();

// Migrations don't support async connection, and this function doesn't need to be async
run_with_connection(options, PgConnection::establish(&db_url)?)
}

fn run_replaceable_schema<Conn>(conn: &mut Conn) -> LemmyResult<()>
where
Conn: Connection<Backend = Pg>,
{
conn.transaction(|conn| {
conn
.batch_execute(&replaceable_schema())
Expand All @@ -266,7 +283,10 @@ fn run_replaceable_schema(conn: &mut PgConnection) -> LemmyResult<()> {
})
}

fn revert_replaceable_schema(conn: &mut PgConnection) -> LemmyResult<()> {
fn revert_replaceable_schema<Conn>(conn: &mut Conn) -> LemmyResult<()>
where
Conn: Connection<Backend = Pg>,
{
conn
.batch_execute("DROP SCHEMA IF EXISTS r CASCADE;")
.with_context(|| format!("Failed to revert SQL files in {REPLACEABLE_SCHEMA_PATH}"))?;
Expand All @@ -277,10 +297,13 @@ fn revert_replaceable_schema(conn: &mut PgConnection) -> LemmyResult<()> {
Ok(())
}

fn run_selected_migrations(
conn: &mut PgConnection,
fn run_selected_migrations<Conn>(
conn: &mut Conn,
options: &Options,
) -> diesel::migration::Result<()> {
) -> diesel::migration::Result<()>
where
Conn: MigrationHarness<Pg>,
{
let mut wrapper = MigrationHarnessWrapper {
conn,
options,
Expand Down