首页 > 解决方案 > 超时时如何重试阻塞IO操作?

问题描述

如何处理IOHaskell 中的阻塞操作?如何将此IO操作放在范围内并从另一种方法管理此范围?如果达到超时,我将重新调用此方法。abort通常在其他语言中,如果我在可配置的时间内没有得到结果,我可能会将它放在一个单独的线程中。(定时器是外部的。)

就我而言:我有很多,retries假设我想执行IO一个超时操作。当且仅当数量大于 0时,如何将IO操作置于超时范围内,以便在超时到期后调用它。retries

基本上:考虑到我们的IO动作ioMethod::IO String(我还没有查看 Haskell 的套接字库),我们假设它是一个黑盒子,

module Retry where

import IOExternal(ioMethod)

retryFunc :: Int -> IO String
retryFunc retries=do
            msg<-retry 5 100 IOExternal 
            return msg

retry :: Int -> Int -> IOExternal -> IO String
retry retries timeout ioMethod = go retries timeout "" where
        go 0       timeout ioMethod  msg =
                    if msg=="" then return "Max Retries reached" 
                               else return msg

        go retries timeout ioMethod  msg counter
               = gogo retries timeout counter msg  where
                     gogo retries timeout 0 msg = return ""
                     gogo retries timeout counter msg
                        = ioMethod>>=gogo retries timeout counter-1 

我不知道如何为最后一个条件/线建模。

PS我还不熟悉Haskell中的线程(这里是初学者),我确实认为超时范围应该在不同的线程中执行,并且不知何故我需要从我的主程序中检查它,或者召回它(如果重试> 0) 或结束 main 方法。

标签: haskellioretry-logic

解决方案


您可以使用timeout为任何阻塞调用添加超时,以及用于重试的简单递归:

retry :: Int -> Int -> IO a -> IO (Maybe a)
retry 0 _ _ = return Nothing
retry numRetries microseconds action = do
    result <- timeout microseconds action
    case result of
        Nothing -> retry (numRetries-1) microseconds action
        Just a  -> return (Just a)

不过,请阅读文档以了解有关 FFI 内容的警告。


推荐阅读