Hasql session and IO
I wrote a function
app :: Request -> H.Session H.Postgres IO Response
which accepts web requests and builds responses (consult the database if necessary). To actually send the answers, I did a wrapper
runApp :: H.Postgres -> H.SessionSettings -> Application
runApp pg sess req respond =
respond =<< H.session pg sess (app req)
I pass this Warp s function runSettings
to loop continuously and process requests:
runSettings appSettings $ runApp pgSettings sessSettings
However, this is very bad because it creates a new session for each request, which defeats the purpose of the connection pooling and prepared statements.
I would like to call runSettings
inside H.session
and not vice versa. However, it runSettings
has a signature Settings -> Application -> IO ()
and once inside IO
I lost access to the session. Is there a way to get back inside Session b m r
?
This is the answer to a question from a private letter.
source to share
Yes, in your example you are creating a new session for every request, which is not acceptable.
First of all, it Session
is a fair and alias for the reader monad mapper , which gives you direct access to the pool. Therefore, you can always:
session postgresSettings sessionSettings $ do
-- session' :: H.Session b m r -> m r
session' <- flip runReaderT <$> ask
let runApp request respond =
respond =<< session' (app request)
liftIO $ do
-- run warp here
Secondly, it ReaderT
has an instance MonadBaseControl
that is intended for similar templates.
source to share