Code reload in umbrella app not working

I have an umbrella app with two apps - web (phoenix 1.3.0) and api (ecto).
When I make any changes to the code files, I can sometimes see that in the next request the file gets recompiled, but the new code is never executed. Sometimes the file doesn’t even get recompiled.
When I run it via iex -S mix phx.server and I manually call recompile() after changing code, it also returns :noop.

The only thing that works is stopping and restarting the server, which is really annoying. I am running the dev configuration with default settings, i.e., code reloading is enabled.
Any ideas what could be the reason and how to fix this?

1 Like

Can you create a minimal repository that reproduces your problem?

Only thing I can imagine right now, is that your request is processed by an old version of a changed module, while only the next on will be done by the new version. I’m not sure how hard the code-reloader enforces the reloading and upgrading of processes.

Also for some changes you have to restart the server, thats just how phoenix works.

Last but not least, in an umbrella there is only the web portion watched as far as I remember, so changes in your api-sub-app will not trigger any recompiling at all.

Still, this are only rough guesses based on only my sparse knowledge about phoenix and limited info about your project

@mpoeter how do you start the app? Do you start it from the root directory of the umbrella, or do you start it from the root directory of apps/web ?

It should work as long as you start the app from the root directory of umbrella project.

1 Like

Thanks for the quick response!
I start it from the root directory. I am aware that for some changes a restart is necessary, but that should definitely not be the case for my changes.
After some more experiments it looks like the recompilation works only for the first change, but not for any subsequent changes, i.e.:

  • start phoenix
  • change something
  • new request -> code gets recompiled, but old code is used
  • change something
  • new request -> nothing happens

The Phoenix.CodeReload.Server process is running and I don’t see any errors reported.

Does sound awfully like a bug to me then. If you create the minimal repo example like @NobbZ suggested that will be helpful.

I agree, it awfully sounds like a bug to me too! But I can’t image that I am the first and only person that is affected - especially since Pheonix 1.3 has been around for a while already.

I will try to get some more information and maybe I can manage to build a minimal example to reproduce this…

There do pop up problems regarding code-reloading and -recompiling all the time, so far most of them were to explain by shared volumes in VM/container when clocks went out of sync or fsnotify didn’t fire properly. Or even just because one was in windows were one needs to poll all files and thus the checking was simply slow.

I haven’t so far encountered problems that weren’t backed by one of these…

To be fair, I have occasional situation where the code does not recompile after I change. And I’m on vanilla Linux (Arch), not inside a VM. This happens like once a week or once a forthnight, but I am aware that it does get stuck from time to time and just need to shutdown/restart server. That said, this happens very rarely.

I am on a native Ubuntu 17.04 with Elixir 1.5.1 and OTP 20. After a restart it seems to recognize changes more reliably, but the newly compiled modules are not used - new request are still handled by the old code. This is starting to look really weird…

I just tried this with freshly generated apps (both, umbrella and non-umbrella) and I experience exactly the same behavior. :sob: So this seems to be a problem with my machine/setup.

Until about a week ago I was working with on a non-umbrella app with Phoenix 1.2 and Elixir 1.4.2 and everything worked fine. :confused:

Maybe code reloading has changed in otp 20? Even for my small Phoenix projects I do not use code reloading. I just run tests. All the stuff that needs visual testing is postponed until design phase.

I am definitely not a mix or phoenix person but I do wonder if you are sure that the recompiled code is actually reloaded into the system? The Erlang system doesn’t do this by default just because there happens to be a newer version lying around, you have to explicitly reload modules. Again I don’t know if mix does this for you.

Mix does not, but Phoenix has a dev-time code reloader included by default (optional though).

This did not seem like it was at dev-time but at run-time.

Oh by dev time I mean the MIX_ENV=dev environment. Phoenix’s default template only enables the code reloader in the dev.exs config file, leaving it disabled in all others. :slight_smile:

What happens when MIX_ENV=prod for building the “production” system?

Then the prod.exs config file is run, which does not include things like the hot-code-reloaders, live reloading, stacktrace displayer, etc… All configurable though. :slight_smile:

EDIT: Specifically, at the bottom of config.exs is this:

import_config "#{Mix.env}.exs"

By default (which of course the user can remove if they want). Mix.env/0 just returns the environment set in the system environment (defaulting to dev), and import_config/1 just runs the specified file as a config at this point. The environments and settings and all are entirely configurable, it just contains a dev, prod, and test by default. :slight_smile:

Ah! Then my question then is if you have built with prod and you want to update your system hwo do you do it?

1 Like

Distillery Releases, either hot-code swap or roll-upgrade it. :slight_smile:

(Or console in and reload modules manually?)

Again ah!

1 Like

Check is inotify-tools is installed/running correctly. (or reinstall)

1 Like