
On Thu, May 6, 2010 at 3:24 PM, Michael Snoyman
On Thu, May 6, 2010 at 9:13 AM, Bryan O'Sullivan
wrote: On Wed, May 5, 2010 at 10:51 PM, Michael Snoyman
wrote: * When a connection is released, is goes to the end of the pool, so connections get used evenly (not sure if this actually matters in practice).
In practice, you're better off letting idle connections stay that way, because then your DB server can close connections and free up resources. In other words, when you're done with a connection, put it at the front of the reuse queue, not the back. You'll also want to handle the possibility that a connection that you grab from the pool has been closed by the server. Many connection pooling implementations I've seen get this wrong in subtle or expensive ways.
Thanks for the feedback. I've gone ahead and implemented a simple resource pool module. Since I need it to work with monad transformer stacks, I've built it on top of MonadCatchIO-transformers. I've put the code up in a gist on github[1]. I would appreciate if anyone could review this, especially to make sure the exception handling code is correct. block and unblock in particular concern me. Thanks, Michael [1] http://gist.github.com/392078
I also have a suggestion for your design. (Note however that I don't have much experience with resource pools.) In your current design a Pool has a fixed maximum number of opened resources. I can imagine situations where the maximum number of opened resources can change dynamically. For example due to plugging in (or out) a new blade server at run-time which will increase (or decrease) the maximum number of resources that can be handled. So what about changing: createPool :: IO a -> Int -> IO (Pool a) to: createPool :: IO (Maybe a) -> IO (Pool a) so, instead of statically storing the maximum number of opened resources (Int), the resource creation function will decide itself when it has created enough (Maybe a). Regards, Bas