Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document how to use Domainslib from Eio #489

Merged
merged 1 commit into from
Apr 18, 2023

Conversation

talex5
Copy link
Collaborator

@talex5 talex5 commented Apr 17, 2023

@talex5 talex5 added the documentation Improvements or additions to documentation label Apr 17, 2023
@talex5 talex5 mentioned this pull request Apr 17, 2023
25 tasks
@talex5
Copy link
Collaborator Author

talex5 commented Apr 17, 2023

I've expanded the example a bit to show how to start the main loop, due to some confusion in https://discuss.ocaml.org/t/interaction-between-eio-and-domainslib-unhandled-exceptions/11971.

```ocaml
let pool = Domainslib.Task.setup_pool ~num_domains:2 ()

let fib n = ... (* Some Domainslib function *)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it makes sense to stress that you cannot perform a call that may perform an (Eio) effect in the Domainslib async task because that may be run in a different domain that no longer has the effect handler installed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. I've added a bit of text saying you can mostly only use functions from the appropriate library in each domain.

@talex5 talex5 merged commit 8ce7ede into ocaml-multicore:main Apr 18, 2023
@talex5 talex5 deleted the domainslib branch April 18, 2023 10:09

let run_in_pool fn x =
let result, set_result = Promise.create () in
let _ : unit Domainslib.Task.promise = Domainslib.Task.async pool (fun () ->
Copy link
Contributor

@polytypic polytypic Apr 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially assumed that the send that happens internally with Task.async would be safe to call from non-domainslib domains, but as I'm now looking into adding POC domain local await support to domainslib, I realize that this works somewhat accidentally.

When you create the pool

let pool = Domainslib.Task.setup_pool ~num_domains:2 ()

the requsted n=2 domains are started. Additionally an internal "multi channel" is created with n+1 capacity. The +1 reserves an extra internal "channel" for the domain that calls Task.run.

When Task.async is called, it looks up the internal channel for the current domain. If no channel has already been allocated for the current domain, it then allocates a channel for the domain from the reserved n+1. This works as long as Task.async is only called from a single additional domain. If you had two (or more) Eio domains, then only one of those could call Task.async.

Copy link
Collaborator Author

@talex5 talex5 Apr 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. I guess Task.run has the same limitation, then? Would be worth documenting that (in Domainslib and here).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think it has the same limitation.

At any rate, I'm looking into how to potententially change that to be more domain safe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants