如何发送多个 TCP 消息并在一个成功后继续
How to send multiple TCP messages and continue when one has succeeded
我目前正在编写一些网络代码,我需要发送大量消息,然后等待单个响应。
假设我有一个函数 returns 我有一个套接字的输入和输出通道:
let resps = List.map uris ~f:(fun uri ->
let%lwt (ic,oc) = connect uri in
let%lwt () = Lwt_io.write_value oc msg in
Lwt_io.read_value ic
) in
Lwt.pick resps
我对此的理解是,pick 在 resps
中完成承诺后应该取消任何正在进行的请求。问题是,如果这些连接中的任何一个 fails/is 被拒绝,则会引发异常 Unix.ECONNREFUSED
.
我的问题是强制 Lwt.pick
忽略异常的正确语义是什么?
到目前为止我想到的选项是抓住
请求中的异常显式:
let resps = List.map uris ~f:(fun uri ->
try
let%lwt (ic,oc) = connect uri in
let%lwt () = Lwt_io.write_value oc msg in
Lwt_io.read_value ic
with Unix_error (e,_,_) -> ...
) in
Lwt.pick resps
但我不确定 Lwt.pick
在什么情况下会认为这些承诺被拒绝了?
更新:我现在正在处理带有可取消、无法实现的承诺的错误:
fst @@ Lwt.task ()
这感觉很老套,但到目前为止似乎有效。
显式处理异常是对的。当您显式拒绝 Lwt 承诺时(使用 Lwt.fail
),或者当异常被 Lwt 捕获时,在本应返回承诺的回调中(例如您将传递给 Lwt.bind
的回调),Lwt 承诺将被拒绝).
但是,为了处理调用 Lwt 的代码中的异常,您必须使用 try%lwt
而不是普通的 try
.
我目前正在编写一些网络代码,我需要发送大量消息,然后等待单个响应。
假设我有一个函数 returns 我有一个套接字的输入和输出通道:
let resps = List.map uris ~f:(fun uri ->
let%lwt (ic,oc) = connect uri in
let%lwt () = Lwt_io.write_value oc msg in
Lwt_io.read_value ic
) in
Lwt.pick resps
我对此的理解是,pick 在 resps
中完成承诺后应该取消任何正在进行的请求。问题是,如果这些连接中的任何一个 fails/is 被拒绝,则会引发异常 Unix.ECONNREFUSED
.
我的问题是强制 Lwt.pick
忽略异常的正确语义是什么?
到目前为止我想到的选项是抓住 请求中的异常显式:
let resps = List.map uris ~f:(fun uri ->
try
let%lwt (ic,oc) = connect uri in
let%lwt () = Lwt_io.write_value oc msg in
Lwt_io.read_value ic
with Unix_error (e,_,_) -> ...
) in
Lwt.pick resps
但我不确定 Lwt.pick
在什么情况下会认为这些承诺被拒绝了?
更新:我现在正在处理带有可取消、无法实现的承诺的错误:
fst @@ Lwt.task ()
这感觉很老套,但到目前为止似乎有效。
显式处理异常是对的。当您显式拒绝 Lwt 承诺时(使用 Lwt.fail
),或者当异常被 Lwt 捕获时,在本应返回承诺的回调中(例如您将传递给 Lwt.bind
的回调),Lwt 承诺将被拒绝).
但是,为了处理调用 Lwt 的代码中的异常,您必须使用 try%lwt
而不是普通的 try
.