仅从子线程中接收第一个异常

时间:2019-03-01 11:57:01

标签: haskell

上下文:

我有一台服务器,该服务器可以抵抗依赖性问题(例如,发生故障的远程服务)。

首先,该服务器进入运行状况检查循环,当依赖项运行状况良好时,我将其启动。 然后,如果有任何请求(子线程)抛出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 ...

0 个答案:

没有答案