Skip to content

Commit

Permalink
Refactor the diesel pool support
Browse files Browse the repository at this point in the history
This commit refactors the support for connection pools for diesel.
Instead of only allowing `r2d2` based pools we now abstract the actual
pool away. It also adds support for `deadpool-diesel` based pools as alternative.
  • Loading branch information
weiznich committed Oct 25, 2023
1 parent c2b2b8f commit 042cc60
Show file tree
Hide file tree
Showing 5 changed files with 354 additions and 125 deletions.
10 changes: 7 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,19 @@ jobs:
docker: false

- store: mysql_store
features: diesel-store,diesel/mysql
features: diesel-store,diesel/mysql,diesel-r2d2
docker: true

- store: postgres_store
features: diesel-store,diesel/postgres
features: diesel-store,diesel/postgres,diesel-r2d2
docker: true

- store: diesel_store
features: diesel-store
features: diesel-store,diesel-r2d2
docker: false

- store: diesel_store_deadpool
features: diesel-store,diesel-deadpool
docker: false

steps:
Expand Down
17 changes: 16 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ postgres-store = ["sqlx/postgres", "sqlx-store"]
mysql-store = ["sqlx/mysql", "sqlx-store"]
moka-store = ["moka"]
diesel-store = ["dep:diesel", "tokio/rt", "rmp-serde"]
diesel-r2d2 = ["diesel/r2d2"]
diesel-deadpool = ["dep:deadpool-diesel", "dep:deadpool"]

[dependencies]
async-trait = "0.1.73"
Expand Down Expand Up @@ -58,9 +60,10 @@ sqlx = { optional = true, version = "0.7.2", features = [
tokio = { optional = true, version = "1.32.0", default-features = false }
moka = { optional = true, version = "0.12.0", features = ["future"] }
diesel = { optional = true, default-features = false, version = "2.1", features = [
"r2d2",
"time",
] }
deadpool-diesel = { version = "0.5", optional = true }
deadpool = { version ="0.10", optional = true }

[dev-dependencies]
axum = "0.6.20"
Expand Down Expand Up @@ -132,6 +135,7 @@ required-features = [
"diesel-store",
"diesel/sqlite",
"continuously-delete-expired",
"diesel-r2d2",
]


Expand All @@ -142,4 +146,15 @@ required-features = [
"diesel-store",
"diesel/sqlite",
"continuously-delete-expired",
"diesel-r2d2",
]

[[example]]
name = "diesel-deadpool"
required-features = [
"axum-core",
"diesel-store",
"diesel/sqlite",
"continuously-delete-expired",
"diesel-deadpool",
]
69 changes: 69 additions & 0 deletions examples/diesel-deadpool.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::net::SocketAddr;

use axum::{
error_handling::HandleErrorLayer, response::IntoResponse, routing::get, BoxError, Router,
};
use deadpool_diesel::{Manager, Pool};
use diesel::prelude::*;
use http::StatusCode;
use serde::{Deserialize, Serialize};
use time::Duration;
use tower::ServiceBuilder;
use tower_sessions::{
diesel_store::DieselStore, session_store::ExpiredDeletion, Session, SessionManagerLayer,
};

const COUNTER_KEY: &str = "counter";

#[derive(Serialize, Deserialize, Default)]
struct Counter(usize);

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let manager = Manager::<SqliteConnection>::new(":memory:", deadpool_diesel::Runtime::Tokio1);
let pool = Pool::builder(manager).max_size(1).build()?;
let session_store = DieselStore::new(pool);
session_store.migrate().await?;

let deletion_task = tokio::task::spawn(
session_store
.clone()
.continuously_delete_expired(tokio::time::Duration::from_secs(60)),
);

let session_service = ServiceBuilder::new()
.layer(HandleErrorLayer::new(|_: BoxError| async {
StatusCode::BAD_REQUEST
}))
.layer(
SessionManagerLayer::new(session_store)
.with_secure(false)
.with_max_age(Duration::seconds(10)),
);

let app = Router::new()
.route("/", get(handler))
.layer(session_service);

let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await?;

deletion_task.await??;

Ok(())
}

async fn handler(session: Session) -> impl IntoResponse {
let counter: Counter = session
.get(COUNTER_KEY)
.expect("Could not deserialize.")
.unwrap_or_default();

session
.insert(COUNTER_KEY, counter.0 + 1)
.expect("Could not serialize.");

format!("Current count: {}", counter.0)
}
Loading

0 comments on commit 042cc60

Please sign in to comment.