2
2
3
3
use std:: default:: Default ;
4
4
use std:: sync:: Mutex ;
5
+ use std:: fmt;
5
6
6
7
pub trait PoolManager < C , E > {
7
8
fn connect ( & self ) -> Result < C , E > ;
@@ -19,6 +20,37 @@ impl Default for Config {
19
20
}
20
21
}
21
22
23
+ impl Config {
24
+ pub fn validate ( & self ) -> Result < ( ) , ConfigError > {
25
+ Ok ( ( ) )
26
+ }
27
+ }
28
+
29
+ #[ deriving( PartialEq , Eq ) ]
30
+ pub enum ConfigError {
31
+ }
32
+
33
+ impl fmt:: Show for ConfigError {
34
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
35
+ Ok ( ( ) )
36
+ }
37
+ }
38
+
39
+ #[ deriving( PartialEq , Eq ) ]
40
+ pub enum NewPoolError < E > {
41
+ InvalidConfig ( ConfigError ) ,
42
+ ConnectionError ( E ) ,
43
+ }
44
+
45
+ impl < E : fmt:: Show > fmt:: Show for NewPoolError < E > {
46
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
47
+ match * self {
48
+ InvalidConfig ( ref error) => write ! ( f, "Invalid Config: {}" , error) ,
49
+ ConnectionError ( ref error) => write ! ( f, "Unable to create connections: {}" , error) ,
50
+ }
51
+ }
52
+ }
53
+
22
54
struct PoolInternals < C > {
23
55
conns : Vec < C > ,
24
56
}
@@ -30,23 +62,56 @@ pub struct Pool<C, M> {
30
62
}
31
63
32
64
impl < C : Send , E , M : PoolManager < C , E > +Default > Pool < C , M > {
33
- pub fn new ( config : Config ) -> Pool < C , M > {
65
+ pub fn new ( config : Config ) -> Result < Pool < C , M > , NewPoolError < E > > {
34
66
Pool :: with_manager ( config, Default :: default ( ) )
35
67
}
36
68
}
37
69
38
70
impl < C : Send , E , M : PoolManager < C , E > > Pool < C , M > {
39
- pub fn with_manager ( config : Config , manager : M ) -> Pool < C , M > {
40
- Pool {
71
+ pub fn with_manager ( config : Config , manager : M ) -> Result < Pool < C , M > , NewPoolError < E > > {
72
+ match config. validate ( ) {
73
+ Ok ( ( ) ) => { }
74
+ Err ( err) => return Err ( InvalidConfig ( err) )
75
+ }
76
+
77
+ let mut internals = PoolInternals {
78
+ conns : vec ! [ ] ,
79
+ } ;
80
+
81
+ for _ in range ( 0 , config. initial_size ) {
82
+ match manager. connect ( ) {
83
+ Ok ( conn) => internals. conns . push ( conn) ,
84
+ Err ( err) => return Err ( ConnectionError ( err) ) ,
85
+ }
86
+ }
87
+
88
+ Ok ( Pool {
41
89
config : config,
42
90
manager : manager,
43
- internals : Mutex :: new ( PoolInternals {
44
- conns : vec ! [ ]
45
- } ) ,
91
+ internals : Mutex :: new ( internals) ,
92
+ } )
93
+ }
94
+
95
+ pub fn get < ' a > ( & ' a self ) -> Result < PooledConnection < ' a , C , M > , E > {
96
+ let mut internals = self . internals . lock ( ) ;
97
+
98
+ loop {
99
+ match internals. conns . pop ( ) {
100
+ Some ( conn) => {
101
+ return Ok ( PooledConnection {
102
+ pool : self ,
103
+ conn : Some ( conn)
104
+ } )
105
+ }
106
+ None => internals. cond . wait ( ) ,
107
+ }
46
108
}
47
109
}
48
110
49
111
fn put_back ( & self , conn : C ) {
112
+ let mut internals = self . internals . lock ( ) ;
113
+ internals. conns . push ( conn) ;
114
+ internals. cond . signal ( ) ;
50
115
}
51
116
}
52
117
0 commit comments