diff --git a/README.md b/README.md index d24d4243..f78a5876 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,23 @@ match conn.try_update(query, params) { } ``` +Connection Pooling +------------------ +A very basic fixed-size connection pool is provided in the `pool` module. A +single pool can be shared across tasks and `get_connection` will block until a +connection is available. +```rust +let pool = PostgresConnectionPool::new("postgres://postgres@localhost", 5) + .unwrap(); + +for _ in range(0, 10) { + do task::spawn_with(pool.clone()) |pool| { + let conn = pool.get_connection(); + conn.query(...); + } +} +``` + Type Correspondence ------------------- Rust-Postgres enforces a strict correspondence between Rust types and Postgres diff --git a/src/pool/mod.rs b/src/pool/mod.rs index f9bbcd52..51b460de 100644 --- a/src/pool/mod.rs +++ b/src/pool/mod.rs @@ -9,31 +9,9 @@ use super::{PostgresConnection, PostgresTransaction}; use super::types::ToSql; -pub struct PostgresConnectionPoolConfig { - initial_size: uint, - min_size: uint, - max_size: uint -} - -impl PostgresConnectionPoolConfig { - fn validate(&self) { - assert!(self.initial_size >= self.min_size); - assert!(self.initial_size <= self.max_size); - } -} - -pub static DEFAULT_CONFIG: PostgresConnectionPoolConfig = - PostgresConnectionPoolConfig { - initial_size: 3, - min_size: 3, - max_size: 15 - }; - struct InnerConnectionPool { url: ~str, - config: PostgresConnectionPoolConfig, pool: ~[PostgresConnection], - size: uint, } impl InnerConnectionPool { @@ -41,7 +19,6 @@ impl InnerConnectionPool { match PostgresConnection::try_connect(self.url) { Ok(conn) => { self.pool.push(conn); - self.size += 1; None } Err(err) => Some(err) @@ -56,18 +33,14 @@ pub struct PostgresConnectionPool { } impl PostgresConnectionPool { - pub fn new(url: &str, config: PostgresConnectionPoolConfig) + pub fn try_new(url: &str, pool_size: uint) -> Result { - config.validate(); - let mut pool = InnerConnectionPool { url: url.to_owned(), - config: config, pool: ~[], - size: 0, }; - while pool.size < pool.config.initial_size { + while pool.pool.len() < pool_size { match pool.new_connection() { None => (), Some(err) => return Err(err) @@ -79,6 +52,13 @@ impl PostgresConnectionPool { }) } + pub fn new(url: &str, pool_size: uint) -> PostgresConnectionPool { + match PostgresConnectionPool::try_new(url, pool_size) { + Ok(pool) => pool, + Err(err) => fail!("Unable to initialize pool: %s", err.to_str()) + } + } + pub fn try_get_connection(&self) -> Result { let conn = unsafe { @@ -108,7 +88,7 @@ impl PostgresConnectionPool { // Should be a newtype pub struct PooledPostgresConnection { priv pool: PostgresConnectionPool, - // Todo remove the Option wrapper when drop takes self by value + // TODO remove the Option wrapper when drop takes self by value priv conn: Option } diff --git a/src/pool/test.rs b/src/pool/test.rs index 613ed600..52d38023 100644 --- a/src/pool/test.rs +++ b/src/pool/test.rs @@ -5,18 +5,12 @@ use std::cell::Cell; use extra::comm::DuplexStream; use extra::future; -use postgres::pool::{PostgresConnectionPool, PostgresConnectionPoolConfig}; +use postgres::pool::PostgresConnectionPool; #[test] // Make sure we can take both connections at once and can still get one after fn test_pool() { - let config = PostgresConnectionPoolConfig { - initial_size: 2, - min_size: 2, - max_size: 2 - }; - let pool = PostgresConnectionPool::new("postgres://postgres@localhost", - config).unwrap(); + let pool = PostgresConnectionPool::new("postgres://postgres@localhost", 2); let (stream1, stream2) = DuplexStream::<(), ()>();