Simplify connection pool
It's going to just be fixed size for now
This commit is contained in:
parent
fa472cf312
commit
498d2e7b26
17
README.md
17
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
|
Type Correspondence
|
||||||
-------------------
|
-------------------
|
||||||
Rust-Postgres enforces a strict correspondence between Rust types and Postgres
|
Rust-Postgres enforces a strict correspondence between Rust types and Postgres
|
||||||
|
@ -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>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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::<(), ()>();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user