haskell - 超时时如何重试阻塞IO操作?
问题描述
如何处理IO
Haskell 中的阻塞操作?如何将此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 方法。
解决方案
您可以使用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 内容的警告。
推荐阅读
- java - 在 Spring 中向 Apache Kafka 主题发送 json 有效负载
- android - com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:应为 BEGIN_ARRAY,但在第 1 行第 3 列路径 $[0] 处为 BEGIN_OBJECT
- java - @ColumnResult 在 JPA 2.0 中映射到 Character 而不是 String
- python - 有什么方法可以禁用 BeautifulSoup 的 Unicode 解码?
- kubernetes - 无法在 Kubernetes 裸机部署的 pod 上挂载 OpenEBS 创建的 PVC
- c# - 通过 Https 发送数据时值发生变化
- firefox - 如何解决“已建立的库必须单独包含”评论 Firefox Add On review?
- apache-spark - 如何在 SnappyData 中获取外部表 jdbc url
- asp.net - 增强 ASP.NET Web 窗体项目以支持路由
- php - 如何检查字符串是否包含“x”但不包含“xy”