如何在 Haskell 中创建一个线程,如果由于任何原因被杀死,该线程将重新启动?

问题描述 投票:0回答:1

首先一些背景知识,我有一个要求,我需要有一个需要每 10 分钟更新一次的配置(通过从数据库或 API 调用获取)(例如每 10 分钟过期的会话令牌)并且它需要可用于我的网络服务器应用程序。

我提出的解决方案是创建一个单独的长时间运行的线程,它将每 10 分钟刷新一次配置。我将在应用程序启动期间创建此线程,并且只要应用程序正在运行,就需要此线程继续运行。如果这个线程由于某些异常而被杀死,我需要自动重新启动它,以便它可以继续完成其工作。

我尝试使用

try
来处理线程被终止时可能引发的任何异常,但它似乎没有检测或捕获异常。

我使用的代码:

restartableThread :: IO () -> IO ()
restartableThread action = do
  result <- try (forkIO action)
  case result of
    Left (e :: SomeException) -> do
      putStrLn $ "Thread killed due to: " ++ show e
      -- Restart the thread after a delay
      threadDelay 1000000  -- 1 second delay
      restartableThread action
    Right _ -> return ()

有没有其他方法可以确保我的线程不会被杀死,如果它被杀死,它会自动重新启动?

我也愿意接受其他解决此要求的想法。

multithreading haskell servant
1个回答
0
投票

使用

try action
捕获
action
抛出的异常。

try (forkIO action)
不处理操作中的异常,仅处理 forking 操作中的异常,而这实际上永远不会发生。

此函数分叉一个线程,每 10 分钟重复一次操作,或者在操作失败时短暂延迟重试。

startBgJob :: IO () -> IO ()
startBgJob = void (forkIO (forever (threadDelay tenminutes >> retry action)))
  where
    retry action = do
      e <- try action
      case e of
        Left (_ :: SomeException) -> threadDelay onesecond >> retry action
        Right () -> pure ()
    tenminutes = 600 * onesecond
    onesecond = 1000000
© www.soinside.com 2019 - 2024. All rights reserved.