【问题标题】:How to retry blocking IO Action when timeout?超时时如何重试阻塞IO操作?
【发布时间】:2018-08-23 09:28:27
【问题描述】:

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

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

基本上:考虑到我们的 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 

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

P.S 我还不熟悉 Haskell 中的线程(这里是初学者),我确实认为超时作用域应该在不同的线程中执行,并且不知何故我需要从我的主线程中检查它程序,然后调用它(如果 retries>0)或结束 main 方法。

【问题讨论】:

  • 请重新插入正确缩进的代码。请注意,您只需粘贴 .hs 文件中的代码,选择它,然后按 ctrl-k
  • 我重新格式化并做了一些参数简化。
  • 呃,缩进还是错了。导入和顶级定义不得缩进。
  • retry 包提供重试逻辑实现,如果您想避免手动编写。如果您只想通过超时限制IO 操作,base 中还有 timeout 组合器

标签: haskell io retry-logic


【解决方案1】:

您可以使用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 内容的注意事项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-15
    • 2019-10-18
    • 2013-11-16
    相关资源
    最近更新 更多