asynchronous - 从 OCaml/Async 中的延迟列表中获取任何非错误元素

标签 asynchronous error-handling ocaml

假设我有一个功能,例如:

query_server : Server.t -> string Or_error.t Deferred.t

然后我生成一个延迟查询列表:
let queries : string Or_error.t Deferred.t list = List.map servers ~f:query_server

如何获得不失败的第一个查询的结果(或其他错误)。基本上,我想要一个功能,例如:
any_non_error :  'a Or_error.t Deferred.t list -> 'a Or_error.t

另外,我不确定如何以某种方式汇总错误。也许我的函数需要一个额外的参数,例如 Error.t -> Error.t -> Error.t还是有一种标准的方法来组合错误?

最佳答案

一个简单的方法是使用 Deferred.List它包含提升到 Async monad 中的列表操作,基本上是 Kleisli 类别中的容器接口(interface)。我们将按顺序尝试每个服务器,直到第一个服务器准备好,例如,

let first_non_error = 
  Deferred.List.find ~f:(fun s -> query_server s >>| Result.is_ok)

当然不是any_non_error ,因为处理是顺序的。此外,我们正在丢失错误信息(尽管后者很容易修复)。

因此,为了使其并行,我们将采用以下策略。我们将有两个延迟计算,第一个将并行运行所有查询并等待一切就绪,第二个将在收到 Ok 结果后立即确定。如果第一个发生在最后一个之前,则意味着所有服务器都失败了。所以让我们试试:
 let query_servers servers = 
   let a_success,got_success = Pipe.create () in
   let all_errors = Deferred.List.map ~how:`Parallel servers ~f:(fun s -> 
      query_server s >>| function
      | Error err as e -> e
      | Ok x as ok -> Pipe.write_without_pushback x; ok) in
   Deferred.any [
       Deferred.any all_errors;
       Pipe.read a_success >>= function
       | `Ok x -> Ok x
       | `Eof -> assert false
   ]

关于asynchronous - 从 OCaml/Async 中的延迟列表中获取任何非错误元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45253719/

相关文章:

javascript - AJAX打开错误

c# - 多次调用相同的方法并显示进度

c# - 如何使用带有异步操作的 Rx.Nex 扩展 ForEachAsync

c# - 处理文件未找到异常的正确位置在哪里?

delphi - Delphi AV与Try-Except [已关闭]

c++ - 使用 CPPRestSDK 进行客户端进度轮询

django - 类型错误 : __init__() missing 1 required positional argument: 'app_module'

ocaml - 为什么 `;;` 在 utop 中给我一个语法错误?

ocaml - Jane Street 的 ‘Base’ 、 ‘Core’ 和 'Core_kernel' 有什么区别?

installation - OCaml 安装,找不到二进制文件