Hacker News new | ask | show | jobs
by alberth 1159 days ago
Doesn't the use of Rust have to be extremely minimal because ErlangVM has hard time limits on their preemptive scheduler and if your Rust code hasn't finished when preempted, that causes lots of problems.

EDIT: thanks for pointing out where in the article this is talked about.

1 comments

I go into this in the article :) the rustler team has a made a DirtyNif that can work around that, or you can manually yield if you'd like.
Indeed, your (excellent) article addresses this, here's the gist for those following along:

> Change `#[rustler::nif]` to `#[rustler::nif(schedule = "DirtyCpu")]`

> This tells the Rustler and BEAM to automagically schedule this in a way that won't block the entire world while it works. Again amazing, this is called a DirtyNif and is way more difficult to work with when you are manually using this via C.

Essentially, regular NIFs have to be extremely fast (< 1ms) because the VM can't preempt them - they run on the same scheduler threads the BEAM itself uses. Dirty NIFs solve this by running jobs in a completely separate thread pool ("dirty schedulers"). Rustler's docs explain it succinctly (https://docs.rs/rustler/latest/rustler/attr.nif.html):

> For functions that may take some time to return - let’s say more than 1 millisecond - it is recommended to use the `schedule` flag. This tells the BEAM to allocate that NIF call to a special scheduler. These special schedulers are called “dirty” schedulers.

> We can have two types of “lengthy work” functions: those that are CPU intensive and those that are IO intensive. They should be flagged with “DirtyCpu” and “DirtyIo”, respectively.

(Somewhat OT, but since I'm here: excellent article @ peregrine! I really enjoyed the read. Elixir and Rust are such a perfect fit. Plus, some of the specifics will be helpful for certain image-related things I'm actively working on, which is always nice. :) )