Should use resource-pool package instead of 'conn' directly in auth backend
ozataman opened this issue · comments
Connections can die/go-away in long running apps. Not sure if possible, but would be better to use a connection pool if we can find a way
I think the same problem exists for the HDBC abstraction. Currently, this is more or less how you would setup a DB connection and auth in your initializer:
sqli <- liftIO $ connectSqlite3 "resources/guestbook.db"
conn <- nestSnaplet "hdbc" dbConn $ hdbcInit sqli
auth' <- nestSnaplet "auth" auth $
initHdbcAuthManager defAuthSettings session sqli defAuthTable defQueries
What we could do instead is something like this:
let sqli = connectSqlite3 "resources/guestbook.db"
conn <- nestSnaplet "hdbc" dbConn $ hdbcInit sqli
auth' <- nestSnaplet "auth" auth $
initHdbcAuthManager defAuthSettings session sqli defAuthTable defQueries
Where hdbcInit
and initHdbcAuthManager
would setup a pool using createPool
from resource-pool. Alternative implementations, e.g. hdbcInit'
and initHdbcAuthManager'
could be created which allow the end-user to configure the pool.
Open questions: would this work nicely with the HDBC snaplet? Can we do this without the end-user having to know anything about pooling? Does this have a (significant) performance impact?
I've implemented pooling as I proposed. I had to change the type of initHdbcAuthManager
a bit: it now requires an IO conn
instead of a conn
. The alternative initHdbcAuthManager'
takes a IO (Pool conn)
for full control over the pooling. The default pooling configuration in initHdbcAuthManager
should be double-checked, since I just hardcoded some numbers without giving it too much thought. Do you know what would make good default values? I'll update my guestbook demo app tomorrow so I can give this a spin.
Sorry I couldn't respond to your proposal. I think that sounds good. There is really no need for the end user to know about this; in the end, they'll just pass (conn -> XX) type of functions, but various connection errors will be gracefully handled.
I'm not sure what good default values would be in practice, but what I would suggest is something like 1 300 1 so that idle connections are not destroyed that often. We can tweak as necessary once we get some experience. With stripe count of 1 and pool count of 1, this shouldn't be too bad in terms of performance in the default case.
The accented versions are good too, because many cases may want to share pools between hdbc and auth for less overall connection overhead. I'll be using your snaplet soon, so I can provide some more feedback then.
Default values modified. I'll have to think about how to add pooling support to HDBC snaplet itself. The problem is a bit more complex than in the authentication backend, due to the way HasHdbc
is currently set up.
I have a preliminary solution, but it requires a MonadControlIO (Handler b v)
instance. Greg mentioned there's an open ticket for adding this to the Snap codebase. Resolving this issue depends on that.
Resolved in 6d2a827 in the MonadControlIO branch. I've specified a MonadControlIO (Handler b v)
instance in the snaplet, rather than converting the entire framework to monad-control
. So far, it seems to work just fine.
Great to hear. Greg is the master of all things exception in snap, so he would be able to tell much better if this is going to run into any issues.
On Oct 17, 2011, at 4:06 AM, Jurriën Stutterheimreply@reply.github.com wrote:
Resolved in 6d2a827 in the MonadControlIO branch. I've specified a
MonadControlIO (Handler b v)
instance in the snaplet, rather than converting the entire framework tomonad-control
. So far, it seems to work just fine.Reply to this email directly or view it on GitHub:
#2 (comment)