首先一些背景知识,我有一个要求,我需要有一个需要每 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 ()
有没有其他方法可以确保我的线程不会被杀死,如果它被杀死,它会自动重新启动?
我也愿意接受其他解决此要求的想法。
使用
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