Is there an api similar to Lwt.pick in Async.Deferred? The closest that I managed to find is Deferred.any, however it seems the other
Deferred.t doesn’t seem to be determined or cancelled, i.e. in
let any = Deferred.any [d1;d2] ....
d1 is determined
any also becomes determined, however,
d2 is still not determined. How do we cancel
async. Is this not possible?
Consider the following example,
$ cat async_test.ml
open Async let print_determined l = Print.print_string "\nDeferred.t statuses\n"; List.iter ~f:(fun d -> Print.printf "%b\n" (Deferred.is_determined d)) l let determine l = List.iter l ~f:(fun (d, ivar) -> if not (Deferred.is_determined d) then Ivar.fill ivar ()) let () = let ivar1 = ref @@ Ivar.create () in let ivar2 = ref @@ Ivar.create () in let d1 = Deferred.create (fun i -> ivar1 := i) in let d2 = let stdin = Lazy.force Reader.stdin in let stdout = Lazy.force Writer.stdout in Deferred.create (fun i -> ivar2 := i; let rec loop () = Print.print_string "Enter message: "; Reader.read_line stdin >>> function | `Ok line -> Writer.writef stdout "%s\n" line; loop () | `Eof -> Writer.write stdout "Eof\n" in loop ()) in let l = [ d1; d2 ] in let any = Deferred.any l in let _ = any >>= fun _ -> Print.printf "\n[any] is determined now.\n"; determine [ (d1, !ivar1); (d2, !ivar2) ]; print_determined (any :: l); Deferred.unit in print_determined (any :: l); Ivar.fill !ivar2 (); Core.never_returns (Scheduler.go ())
$ cat dune
(executable (name async_any) (libraries core async))
A sample run as follows,
$ dune exec ./async_test.exe
Enter message: Deferred.t statuses false false false [any] is determined now. Deferred.t statuses true true true hello hello Enter message: hello hello Enter message: ^C⏎
In the above, even after
any, d1 and d2 are determined the code in
d2 is still executing. Isn’t this supposed to stop after
d2 is determined?