Hasql的会话和IO

时间:2014-11-17 15:14:10

标签: haskell hasql

我写了一个函数

app :: Request -> H.Session H.Postgres IO Response

接受Web请求并构建响应(根据需要咨询数据库)。为了实际发出回复我做了一个包装

runApp :: H.Postgres -> H.SessionSettings -> Application
runApp pg sess req respond =
  respond =<< H.session pg sess (app req)

我将此函数传递给WarprunSettings以永久循环并处理请求:

runSettings appSettings $ runApp pgSettings sessSettings

然而,这非常糟糕,因为它为每个请求创建了一个新会话,这会破坏连接池和预准备语句的目的。

我想在runSettings内拨打H.session而不是相反。但是,runSettings有一个签名Settings -> Application -> IO (),一旦进入IO,我就无法访问该会话。有没有办法回到Session b m r

这是私人电子邮件中的问题重新发布。

1 个答案:

答案 0 :(得分:3)

是的,在您的示例中,您为每个请求创建了一个新会话,这是不可接受的。

首先,Session is just and alias to the reader monad transformer,它可让您直接访问池。所以你总是这样做:

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 

其次,ReaderT有一个MonadBaseControl实例,用于类似的模式。