以下是以下代码:
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:我希望详细信息足以理解该问题,如有必要,请随时获取更多信息...
答案 0 :(得分:2)
如果很少发生丢失数据库连接的情况,则可以使服务器崩溃,并通过一些监督进程将其重新启动,效果很好。
如果丢失数据库连接非常普遍,以至于您无法忍受客户端超时而无法重启服务器,则可以将重新连接逻辑添加到使用该数据库连接的任何代码中。我通常为此使用resource-pool。我相信,如果适合您的数据库,则只能使用一种资源创建“池”。
通常情况下,建立数据库连接速度很快,因此我认为将传入的请求路由到其他地方不值得付出额外的努力。 withResource
中的resource-pool
会阻塞直到资源准备就绪,因此活动请求可以很容易地等待您重新连接。