# Multiple domains design question in Eio/etc

**URL:** <https://discuss.ocaml.org/t/multiple-domains-design-question-in-eio-etc/15861>\
**Category:** Learning\
**Tags:** multicore, domainslib, eio\
**Created:** [December 28, 2024, 6:51am UTC](https://discuss.ocaml.org/t/multiple-domains-design-question-in-eio-etc/15861 "2024-12-28T06:51:13Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [December 28, 2024, 6:51am UTC](https://discuss.ocaml.org/t/multiple-domains-design-question-in-eio-etc/15861/1 "2024-12-28T06:51:13Z")

</div>

I have an app design question regarding the use of multiple domains in say Eio or some other multicore library. We can do eg

```auto
let num_domains = Domain.recommended_domain_count () - 1
let additional_domains = Eio.Stdenv.domain_manager env, num_domains
...
Cohttp_eio.Server.run ~additional_domains ...

```

…to make the server run on multiple domains (I assume that’s how it works).

But suppose I have another part of my app that uses the [`Eio.Executor_pool`](https://ocaml-multicore.github.io/eio/eio/Eio/Executor_pool/index.html) to run background jobs on multiple cores. And I also need to pass it similar arguments:

```auto
Eio.Executor_pool.create ~sw domain_count:num_domains (Eio.Stdenv.domain_manager env)

```

So do these different functions coordinate to ensure that they don’t create `num_domains + num_domains` domains? Ie, do they check the existing number of domains before creating new ones? Or is that check guaranteed by Eio at a lower level?

---

<div class="post-metadata">

**Author:** ![patricoferris](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/patricoferris/32/3621_2.png) [@patricoferris](https://discuss.ocaml.org/u/patricoferris)\
**Post date:** [December 28, 2024, 12:51pm UTC](https://discuss.ocaml.org/t/multiple-domains-design-question-in-eio-etc/15861/2 "2024-12-28T12:51:13Z")

</div>

Unfortunately the answer is no. The implementation of the `Cohttp_eio.Server` predates `Eio.Executor_pool`. This is why it uses the raw domain spawning API rather than using a pool. In fact, it is `Eio.Net.run_server` that uses the `Domain_manager.run` API – I think there’s a good argument here to change this to using a pool (perhaps an issue for this would be good).

As a workaround, you can wrap the existing domain manager implementation to do something more clever (e.g. use a pool or something like that maybe).

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [December 28, 2024, 3:57pm UTC](https://discuss.ocaml.org/t/multiple-domains-design-question-in-eio-etc/15861/3 "2024-12-28T15:57:01Z")

</div>

Got it. I think two tracking issues will be needed as two APIs will change:

> <https://github.com/ocaml-multicore/eio/issues/791>
>
> This issue is related to the forum discussion https://discuss.ocaml.org/t/multip…le-domains-design-question-in-eio-etc/15861 and the cohttp issue https://github.com/mirage/ocaml-cohttp/issues/1101
> 
> The concern is that including cohttp-eio, multiple parts of an app may be using the raw domain manager to each create their own pools of domains. Instead, they should all coordinate and use the same executor pool.

> <https://github.com/mirage/ocaml-cohttp/issues/1101>
>
> As discussed in the forum: https://discuss.ocaml.org/t/multiple-domains-design-q…uestion-in-eio-etc/15861
> 
> Currently cohttp-eio directly takes the domain manager and the number of domains to create, and creates the new domains itself. However, other parts of the app may also be creating new domains using the domain manager, eg https://ocaml-multicore.github.io/eio/eio/Eio/Executor\_pool/index.html
> 
> one strategy to prevent multiple parts of an app from creating multiple domain pools would be to coordinate by having all of them use the same pool. So, then cohttp-eio should take an \`Eio.Executor\_pool.t\` as an argument instead of taking the domain manager directly.

EDIT: I also want to say that this analysis was fairly trivial thanks to Eio’s design exposing functions which take the domain manager. I think this is a win for the capabilities-based design.

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [December 28, 2024, 5:46pm UTC](https://discuss.ocaml.org/t/multiple-domains-design-question-in-eio-etc/15861/4 "2024-12-28T17:46:43Z")

</div>

Although the `Eio.Executor_pool.submit` function seems to be designed for only _one_ subsystem to have access to the pool and submit coarse-grained jobs to it, not for _multiple_ decoupled subsystems. I can’t see a way for both an HTTP server and an async message queue (eg) subsystem to share the same pool.

EDIT: made a suggestion which I think is pertinent: [Eio.Net.run\_server should take an executor pool instead of the domain manager (maybe?) · Issue #791 · ocaml-multicore/eio · GitHub](https://github.com/ocaml-multicore/eio/issues/791#issuecomment-2564616563)

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [January 4, 2025, 12:57am UTC](https://discuss.ocaml.org/t/multiple-domains-design-question-in-eio-etc/15861/5 "2025-01-04T00:57:47Z")

</div>

OK, I’ve suggested a multi-core runtime strategy, basically:

```ocaml
let () = Par.run @@ env ->
  ...run on multiple cores...

  (* Distribute slices of the array across all worker domains *)
  let result = Par.sum env large_float_array in
  ...

```

So this takes care of starting up the recommended number of domains and running the app across all of them, while also setting up a way to submit parallelized (ie CPU-intensive) tasks and getting a promise of the result.

This is a POC right now (linked above) but I believe this is a good direction: users don’t need to worry about setting up domains, they don’t need to hand over all of the domains to a specific subsystem like the HTTP server, they don’t need to figure out how many domains to allocate for what.

Of course, this is not thoroughly tested or benchmarked right now; more to come. But happy to discuss more.

---

<div class="post-metadata">

**Author:** ![dinosaure](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dinosaure/32/16_2.png) [@dinosaure](https://discuss.ocaml.org/u/dinosaure)\
**Post date:** [January 4, 2025, 9:07am UTC](https://discuss.ocaml.org/t/multiple-domains-design-question-in-eio-etc/15861/6 "2025-01-04T09:07:17Z")

</div>

Sorry to interfere with this question, but I’d just like to mention that this is exactly what Miou offers with `Miou.parallel`:

```ocaml
let () = Miou.run @@ fun () ->
  let result = Miou.parallel sum large_float_array in
  ...

```

You can see the documentation here (with a little example): [`Miou.parallel`](https://ocaml.org/p/miou/latest/doc/Miou/index.html#val-parallel). And about an HTTP server, [`httpcats`](https://github.com/robur-coop/httpcats) is released and actually it follows the pattern you suggest.

---

<div class="post-metadata">

**Author:** ![dbuenzli](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dbuenzli/32/18_2.png) [@dbuenzli](https://discuss.ocaml.org/u/dbuenzli)\
**Post date:** [January 5, 2025, 11:04am UTC](https://discuss.ocaml.org/t/multiple-domains-design-question-in-eio-etc/15861/7 "2025-01-05T11:04:11Z")

</div>

4 posts were split to a new topic: [On concurrency models](https://discuss.ocaml.org/t/on-concurrency-models/15899)

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [January 5, 2025, 12:29am UTC](https://discuss.ocaml.org/t/multiple-domains-design-question-in-eio-etc/15861/10 "2025-01-05T00:29:47Z")

</div>

Hey folks, just a reminder that this thread is meant to be about parallelism/concurrency strategies in Eio. Thanks.

---

<div class="post-metadata">

**Author:** ![bluddy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bluddy/32/104_2.png) [@bluddy](https://discuss.ocaml.org/u/bluddy)\
**Post date:** [January 5, 2025, 6:35am UTC](https://discuss.ocaml.org/t/multiple-domains-design-question-in-eio-etc/15861/12 "2025-01-05T06:35:00Z")

</div>

There’s an interesting discussion going on here regarding domains vs threads as building blocks and the merits of user-defined concurrency. Admins, can we split this discussion thread up?
