Simplify connection pool

It's going to just be fixed size for now
This commit is contained in:
Steven Fackler 2013-09-17 23:08:42 -07:00
parent fa472cf312
commit 498d2e7b26
3 changed files with 29 additions and 38 deletions

View File

@ -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 Type Correspondence
------------------- -------------------
Rust-Postgres enforces a strict correspondence between Rust types and Postgres Rust-Postgres enforces a strict correspondence between Rust types and Postgres

View File

@ -9,31 +9,9 @@ use super::{PostgresConnection,
PostgresTransaction}; PostgresTransaction};
use super::types::ToSql; 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 { struct InnerConnectionPool {
url: ~str, url: ~str,
config: PostgresConnectionPoolConfig,
pool: ~[PostgresConnection], pool: ~[PostgresConnection],
size: uint,
} }
impl InnerConnectionPool { impl InnerConnectionPool {
@ -41,7 +19,6 @@ impl InnerConnectionPool {
match PostgresConnection::try_connect(self.url) { match PostgresConnection::try_connect(self.url) {
Ok(conn) => { Ok(conn) => {
self.pool.push(conn); self.pool.push(conn);
self.size += 1;
None None
} }
Err(err) => Some(err) Err(err) => Some(err)
@ -56,18 +33,14 @@ pub struct PostgresConnectionPool {
} }
impl PostgresConnectionPool { impl PostgresConnectionPool {
pub fn new(url: &str, config: PostgresConnectionPoolConfig) pub fn try_new(url: &str, pool_size: uint)
-> Result<PostgresConnectionPool, PostgresConnectError> { -> Result<PostgresConnectionPool, PostgresConnectError> {
config.validate();
let mut pool = InnerConnectionPool { let mut pool = InnerConnectionPool {
url: url.to_owned(), url: url.to_owned(),
config: config,
pool: ~[], pool: ~[],
size: 0,
}; };
while pool.size < pool.config.initial_size { while pool.pool.len() < pool_size {
match pool.new_connection() { match pool.new_connection() {
None => (), None => (),
Some(err) => return Err(err) 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<PooledPostgresConnection, pub fn try_get_connection(&self) -> Result<PooledPostgresConnection,
PostgresConnectError> { PostgresConnectError> {
let conn = unsafe { let conn = unsafe {
@ -108,7 +88,7 @@ impl PostgresConnectionPool {
// Should be a newtype // Should be a newtype
pub struct PooledPostgresConnection { pub struct PooledPostgresConnection {
priv pool: PostgresConnectionPool, 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<PostgresConnection> priv conn: Option<PostgresConnection>
} }

View File

@ -5,18 +5,12 @@ use std::cell::Cell;
use extra::comm::DuplexStream; use extra::comm::DuplexStream;
use extra::future; use extra::future;
use postgres::pool::{PostgresConnectionPool, PostgresConnectionPoolConfig}; use postgres::pool::PostgresConnectionPool;
#[test] #[test]
// Make sure we can take both connections at once and can still get one after // Make sure we can take both connections at once and can still get one after
fn test_pool() { fn test_pool() {
let config = PostgresConnectionPoolConfig { let pool = PostgresConnectionPool::new("postgres://postgres@localhost", 2);
initial_size: 2,
min_size: 2,
max_size: 2
};
let pool = PostgresConnectionPool::new("postgres://postgres@localhost",
config).unwrap();
let (stream1, stream2) = DuplexStream::<(), ()>(); let (stream1, stream2) = DuplexStream::<(), ()>();