以下是我希望将错误处理纳入其中的代码的要点。
worldHandler :: ProcessState -> JobCount -> IO ()
worldHandler world jCount = do
putStrLn "Entered worldHandler"
jcount <- takeMVar jCount
if jcount > 0
then incrementThenDone jcount
else doJobProcessing jcount
where incrementThenDone jcount = do
putMVar jCount (jcount+1)
doJobProcessing jcount = do
putMVar jCount (jcount+1)
preProcess world
initiateJob world
makeChart world
这是main
。
main :: IO ()
main = do
world <- (newEmptyMVar :: IO ProcessState)
jCount <- (newMVar 0 :: IO JobCount)
installHandler userDefinedSignal1 (Catch $ worldHandler world jCount) Nothing
forever (threadDelay 10000)
功能preProcess
,initiateJob
和makeChart
是我需要的地方
关心错误。这个想法是,如果任何这些功能
失败,我递减jCount
并致电logError
。然后,如果jCount > 0
,再次启动相同的三个函数。如果jCount == 0
,继续等待
下一个信号。
这些功能中的每一个都将开始另一个过程,
readProcessWithExitCode
看起来像我想要的。然后我会用
退出代码以确定成功或失败。
我的一个想法是制作一个[preProcess, initiateJob, makeChart]
。
然后我将函数jobProcessor
映射到此列表。如果其中之一
功能从他们调用的程序中收到了失败,我可以
生成一个execption,map将停止在列表上的映射。
这是一个合理的方法吗?
关于如何处理此问题的一般想法,以及任何问题 我会很感激。
编辑:由于提出了第一个问题,我重新评估了我的解释,并指出它在重要方面不完整。我认为填补了空白。如果没有,请告诉我。
答案 0 :(得分:1)
让我们看看这个序列,暂时搁置计数。
preProcess world
initiateJob world
makeChart world
作为顶级功能,它看起来像
doJobProcessing :: ProcessState -> IO ()
doJobProcessing world = do
preProcess world
initiateJob world
makeChart world
。如果其中任何一个失败,并且(可能)重新启动,我们希望中断该执行流程。
可以使用Haskell异常,也可以不使用。让我们首先看一个没有异常的解决方案,因为它也适用于非IO代码。我不知道你的类型究竟是什么,所以让我们假设它们都是
preProcess, initiateJob, makeChart :: ProcessState -> IO ExitCode
现在这里有一个非常丑陋明显的方法(总是一个好的开始)
doJobProcessing :: ProcessState -> IO ()
doJobProcessing world = do
preProcessStatus <- preProcess world
if preProcessStatus /= ExitSuccess
then jobFail world
else do
initiateJobStatus <- initiateJob world
if initiateJobStatus /= ExitSuccess
then jobFail world
else do
makeChartStatus <- makeChart world
if makeChartStatus /= ExitSuccess
then jobFail world
else return () ---success!!!
jobFail :: ProcessState -> IO ()
jobFail world = do
--some test involving jCount
if --test says to try again
then do
--inc/dec jCount
doJobProcessing world
else do
-- nothing; we give up
return ()
这表现得怎么样? (如果即使makeChart失败,也会从preProcess开始再次尝试。)如果确实如此,那么我将展示如何使用纯Haskell抽象和/或异常简化它。 (如果你想要preProcess,initiateJob和makeChart中的每一个只重新启动它,我将展示一种方法来代替它。)