rustler icon indicating copy to clipboard operation
rustler copied to clipboard

Missing recompilation when changing MIX_ENV

Open jnnks opened this issue 2 years ago • 7 comments

I'm having trouble making rustler compile my crate in release mode. MIX_ENV does not seem to have any impact. Is there a switch I can use somewhere?

On version 0.25.0

jnnks avatar Jul 21 '22 09:07 jnnks

Hmm seems like the build config is stuck on the configuration of the last completed build:

  • rm -fr _build
  • MIX_ENV=prod mix run --no-halt -> release
  • MIX_ENV=dev mix run --no-halt -> debug
  • MIX_ENV=prod mix run --no-halt -> debug
  • rm -fr _build
  • MIX_ENV=prod mix run --no-halt -> release

The other way round (first debug then release) the same issue comes up.

When making changes to the Rust code (provoking a build), the correct config is used.

jnnks avatar Jul 21 '22 15:07 jnnks

I think rustler_mix fails to recompile on changed MIX_ENV, it only considers changes to source files IIRC. We will need to cache that information and recompile on changes.

To work around that for now, you can manually specify the :mode, see https://hexdocs.pm/rustler/Rustler.html#module-configuration-options.

evnu avatar Jul 21 '22 18:07 evnu

Yes thanks, the :mode is a suitable workaround for now.

jnnks avatar Jul 26 '22 10:07 jnnks

I can reproduce this with https://github.com/evnu/rustler_bug_switch_profile.

evnu avatar Sep 12 '22 18:09 evnu

By default, Rustler.Config retrieves the build mode from Mix.env() (here). As noted before, this can be overridden in the use macro. But changing the build mode with MIX_ENV does not result in a reinvocation of Rustler.Compiler.compile_crate/2, and thus no recompile.

The only way I can think of is to resurrect Mix.Tasks.Compile.Rustler and use that compiler to cache Mix.env() in a suitable place. I implemented that in https://github.com/rusterlium/rustler/pull/491. I somewhat dislike that approach, as we need to maintain a cache, and users need to add the :rustler compiler again in their mix.exs. Maybe we should instead get rid of configuring via MIX_ENV instead. If user's still want to use MIX_ENV for the mode, they can do that manually and take care of triggering recompilation. @rusterlium/core ideas?

evnu avatar Sep 12 '22 19:09 evnu

The following doesn't add much to the issue, but more as a hint for other devs when debugging why their NIF performance degrades seemingly out of nowhere:

I also noticed you don't always have to formally switch MIX_ENV for this issue to occur (e.g. run a test). I have an Elixir language server running in vim, which also triggers the switch in MIX_ENV in de background when simply editing an Elixir file in between running MIX_ENV=prod mix run .... The result is that the performance of the NIF degrades considerably, seemingly out of nowhere. Adding mode: :release as stated above fixes this.

basvanwesting avatar Sep 21 '22 12:09 basvanwesting

In general, I've always ended up using release mode in all environments because the incremental compilation usually is pretty fast once you've paid the upfront cost. Obviously this may not be ideal for CI environments, but I think it also depends on the code base.

I've noticed on certain code bases, running in debug mode produces painfully slow test suites.

scrogson avatar Sep 21 '22 22:09 scrogson

With #496, :release will be the default mode. This can be overridden manually in use Rustler.

evnu avatar Nov 09 '22 16:11 evnu