处理所有服务器请求的一个连接

时间:2019-02-26 16:56:16

标签: haskell

以下是以下代码:

start :: Settings -> IO ()
start settings @ Settings {healthCheckLoggerId}  = do
  waitTillHealthy
    healthCheckLoggerId
    settings
    Server.getDependencies
    Server.healthCheck
  Server.getDependencies
   settings
   (runServerOnWarp)

  where

    runServerOnWarp :: Server.Dependencies -> IO()
    runServerOnWarp dependencies @ Server.Dependencies {logger,port} = do
       run port $ application
                    (proxy :: Proxy GSDMonitoringStreamingApi)
                    monitoringServer
                    dependencies

    monitoringServer :: ServantServer GSDMonitoringStreamingApi Server.Dependencies
    monitoringServer dependencies = streamCommand dependencies
      where

        streamCommandResponse :: Server.Dependencies ->
                                 WorkspaceId ->
                                 Handler (PipeStream (Either StreamIssue (Persisted CommandResponse)))
        streamCommandResponse Server.Dependencies {eventStoreClientDependencies} =
          return . toPipes . GsdMonitoring.streamCommandResponse eventStoreClientDependencies

问题说明:

函数Server.getDependencies封装了一个括号模式,该模式用于获得与数据库的连接(该数据库的客户端建议对所有请求使用一个连接,而不对每个请求使用一个连接)。 首先,我正在运行healthCheck,直到一切正常为止,它将一直受阻。每次我测试依赖项的运行状况检查时,每次获取新连接时。环境良好后,我将再次获得Server.Dependencies(数据库连接),并且正在运行服务器。 runServerOnWarp中运行的所有内容均在

-- ^ computation to run in-between部分中执行
bracket
        :: IO a         -- ^ computation to run first (\"acquire resource\")
        -> (a -> IO b)  -- ^ computation to run last (\"release resource\")
        -> (a -> IO c)  -- ^ computation to run in-between
        -> IO c         -- returns the value from the in-between computation

因此所有请求都被执行到该部分中并获得相同的连接,到目前为止一切顺利……因为该部分:

run port $ application
              (proxy :: Proxy GSDMonitoringStreamingApi)
              monitoringServer dependencies

永无止境,我们一直待在computation to run in-between中(除非我杀死该应用...)

现在我遇到的问题是当连接关闭时...。我的所有请求都将返回Left StreamIssue,这很好,但是我必须从Server.getDependencies获得新的连接。我不知道如何正确地做到这一点:-(我想到的骇客是:

1)一个请求具有一个连接

2)当请求流向Left流发出问题时,引发异常,以某种方式重新启动服务器以获取新的依赖项...问题是服务器的客户端永远不会获得Left值,并且2之间的通信剧烈已关闭,因为服务器已重新启动...

您有更清洁的想法吗?

P.S:我希望详细信息足以理解该问题,如有必要,请随时获取更多信息...

1 个答案:

答案 0 :(得分:2)

如果很少发生丢失数据库连接的情况,则可以使服务器崩溃,并通过一些监督进程将其重新启动,效果很好。

如果丢失数据库连接非常普遍,以至于您无法忍受客户端超时而无法重启服务器,则可以将重新连接逻辑添加到使用该数据库连接的任何代码中。我通常为此使用resource-pool。我相信,如果适合您的数据库,则只能使用一种资源创建“池”。

通常情况下,建立数据库连接速度很快,因此我认为将传入的请求路由到其他地方不值得付出额外的努力。 withResource中的resource-pool会阻塞直到资源准备就绪,因此活动请求可以很容易地等待您重新连接。