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.

+3


source to share


1 answer


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.

+3


source







All Articles