上下文:
我有一台服务器,该服务器可以抵抗依赖性问题(例如,发生故障的远程服务)。
首先,该服务器进入运行状况检查循环,当依赖项运行状况良好时,我将其启动。 然后,如果有任何请求(子线程)抛出ServerDownException,我将返回到运行状况检查循环,依此类推...
我遇到的问题是,我可以从不同的子线程(线程处理用户请求)接收许多异常: -第一次异常重新启动过程 -第二个杀死我的程序...
如果您需要一些代码:
start :: Settings -> IO ()
start settings @ Settings {healthCheckLoggerId} = do
waitTillHealthy
healthCheckLoggerId
settings
Server.getDependencies
Server.healthCheck
catch
(Server.getDependencies
settings
(runServerOnWarp))
(\ServerDownException -> start settings)
where
runServerOnWarp :: Server.Dependencies -> IO()
runServerOnWarp dependencies @ Server.Dependencies {port,logger} = do
logInfo logger "Server Up and Running"
serverThreadId <- myThreadId
run port $ application
(proxy :: Proxy GSDReadApi)
(readServer serverThreadId)
dependencies
readServer :: ServerThreadId -> ServantServer GSDReadApi Server.Dependencies
readServer serverThreadId dependencies =
healthCheck serverThreadId dependencies
:<|> streamWorkspace serverThreadId dependencies
where
healthCheck :: ServerThreadId -> Server.Dependencies -> Handler Healthy
healthCheck serverThreadId Server.Dependencies {logger} =
liftIO $ logInfo logger "service health asked" >>
Server.healthCheck dependencies >>=
either
(\error -> do
logInfo logger $ "service unhealthy : " ++ show error
return $ Left $ toException ServerDownException)
(\right -> do
logInfo logger "service healthy"
return $ Right ()) >>=
breakServerOnFailure logger serverThreadId
找到的解决方案:
然后我开始思考如何解决此问题。...我希望根线程仅对孩子抛出的第一个异常敏感,这就是我想出的:
runServerOnWarp :: Server.Dependencies -> IO()
runServerOnWarp dependencies @ Server.Dependencies {logger,port} = do
logInfo logger "Server Up and Running"
serverThreadId <- myThreadId
thethread <- forkIO (
catch
(threadDelay 1000000000000000)
(\ServerDownException -> do
logInfo logger "ServerDownException caught"
throwTo serverThreadId ServerDownException))
run port $ application
(proxy :: Proxy GsdWriteApi)
(writeServer thethread)
dependencies
'threadDelay 1000000000000000'是一个快速而肮脏的解决方案,以查看其是否有效……我想永远永久地阻塞线程,它的唯一目的是重新获得第一个ServerDownException ...