Hello,
I am trying to build something using both eio and domainslib, and I’m quite stumped by their interaction.
According to the readme of eio, calls to various functions require a Eio.Stdenv.t
, most likely given by Eio_main.run
.
On the other hand, according to its documentation domainslib states that “[The run
] function should be used at the top level to enclose the calls to other functions that may await on promises. This includes await
, parallel_for
and its variants. Otherwise, those functions will raise Unhandled
exception.”
Armed with this, I wrote this MWE:
module T = Domainslib.Task
let task pool sink =
T.parallel_for ~start:0 ~finish:1024
~body:(fun i -> if i mod 2 = 0 then Eio.Flow.copy_string "Hello!\n" sink)
pool
let () =
let pool =
T.setup_pool ~num_domains:(Domain.recommended_domain_count () - 1) ()
in
T.run pool (fun () ->
Eio_main.run (fun env ->
let stdout = Eio.Stdenv.stdout env in
task pool stdout));
T.teardown_pool pool
Running this with eio = 0.9, domainslib = 0.5, ocaml = 5.0.0
, on a machine where Domain.recommended_domain_count
is 8 gets the following result:
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Fatal error: exception Stdlib.Effect.Unhandled(Eio_linux__Sched.Alloc)
So, only 8 Hellos instead of the expected 512, and a nice crash to boot.
At first I thought I had messed up my calls to run
functions, and tried swapping Eio_main.run
and T.run
around to check.
Same error.
On more involved examples, I also got the following error:
Fatal error: exception Multiple exceptions:
- Invalid_argument("Cancellation context accessed from wrong domain!")
- Invalid_argument("exit: 1 request(s) still active!")
I don’t really understand how to proceed from here. Are Eio and Domainslib just not supposed to work together? Is there something obvious I missed?
Thanks all