Comment by fud101

1 day ago

I thought elixir devs have cooled on the whole hot reload update or is this different?

Hot code reloading for development (recompile-on-save) has issues, but production hot code loading for zero-downtime deployments is still a core BEAM strength and what this article focuses on.

  • To be fair, I think most apps don't need zero-downtime deployments in the telcom sense.

    Most host have blue-green deploy options which reduce downtime and there are fewer corner cases to deal with.

    I find local recompile very useful for prototyping in development mode. So much so that I have a keyboard shortcut to trigger a recompile. (I don't like recompile on save.)

We run a large distributed cluster (currently 4 DCs spanning the US) and use hot code reload for live patches when needed and rolling deployments for our standard releases.

I'm not using this to update the app itself - which is a docker container that gets updated when I push a new version. I'm simply using the BEAM's code loading capabilities to add client-specific parts to the app while it is running. They are part of the monorepo (and thus part of the app at dev time), but get stripped at build-time so they can be selectively loaded later.

Elixir removed a jankier https://www.erlang.org/doc/apps/sasl/appup.html mechanism that defined how state is upgraded or downgraded, while watching a directory and recompiling a module automatically or manually from the repl is still common

  • > while watching a directory and recompiling a module automatically or manually from the repl is still common

    That makes it sound like the "hot" part has been removed then, and it's just basically a "live reload" rather than "hot code loading", is that right? There is no persistent state and you get a fresh one after the automatic compilation happened?

    • I've used utility functions in Erlang where I make changes, then compile and load all modified modules...

      It's absolutely hot loading, there's persistent state, any fully qualified function calls run in the newest module. The gen_server pattern always calls into your behavior module with fully qualified calls, so those are pretty easy to get into new code at a reasonable time. If you write your own service loop, it's pretty common to call ?MODULE:loop() to enable hotloading there too.

      There's footguns; hotloading is a way to make rapid changes to your system, but sometimes rapid changes isn't what's needed and sometimes the rapid change you make is to go from a partially broken system to a fully broken system. But, there's a virtuous circle when you can make production changes quickly, because you can make a small change and observe and make many follow ups in a single day. With push processes that take a long time, you end up encouraged to make a bigger change one time, otherwise you spend all day waiting for traffic to move between old and new versions, or waiting for instances to deploy, etc.

    • no, for example if you are running a liveview in dev and recompiling your code the liveview does not lose its state and jumps into the new module, unless I'm mistaken.