shahryarjb

shahryarjb

How to keep state of an updated-dependency in run time

Hi, imagine you want to add a new dep in your project without restart your app:

Code.prepend_path(path)
Application.load(timex)
Application.ensure_all_started(timex)

With these 3 functions and a new source which is compiled before, your project can use new deps. But I have a problem to update an installed-app like timex.

For example, I want to update timex to new version: if I call the Application.load(app) and Application.ensure_all_started(app) functions, I can see this error: this dep is already loaded.

So I found another function: Application.unload this can not make timex unload, so it forces me to use Application.stop; This is the place for example I lose the state of timex or the other apps I want to update.

How can keep the states and freeze them (for example a gen server with supervisor, agent), after update I can be able to resume them again?

I have read some of the Erlang documents, so every page call release mode, but I have no idea how it can help me?

Thank you in advance.

Most Liked

Qqwy

Qqwy

TypeCheck Core Team

I believe that an already-installed dependency will be updated as part of a hot-code upgrade of your own main app.

This will trigger all of the loaded GenServer’s code_change/3 methods to fire.
There are three possibilities:

  1. The GenServer has no custom implementation of code_change/3 which means that the default one is used. This one keeps the state the same. This does mean that if the structure of the state that if the new version of the GenServer expects the state to have a different shape, that it will probably crash once the next event arrives. Depending on how it is supervised it will restart after, but it might result in a temporary crash and some lost state and/or a lost event.
  2. The GenServer has a custom implementation of code_change/3. Assuming it is implemented correctly (and does not raise), the GenServer will be upgraded perfectly. Note that not many libraries implement custom code_change/3s for their servers.
  3. The GenServer has a custom implementation of code_change/3 which raises an exception. This prevents the hot-code upgrade of this particular OTP application (and usually your hot-code upgrade as a whole) to finish; everything will stay at/revert to the previously-used version. This is for instance commonly done for modules containing NIFs (natively-implemented functions) because making native code backwards/forwards compatible is again much more difficult.
Qqwy

Qqwy

TypeCheck Core Team

You do not need to stop an application first before upgrading it.

Maybe I am misunderstanding what you’re trying to accomplish?

NobbZ

NobbZ

To do hotcode reloading, you actually need to have the dependencies written for that, and you need to provide release upgrade scripts, which describe which modules in which application needs to get replaced.

There are probably more low level tools that could do hot reloading without releases, though it still requires that the applications are built with hot code upgrades in mind and that their GenServers or whatever keeps the state is able to convert old state to new state.

shahryarjb

shahryarjb

I think I missed in my questions!!
When I use Application.stop :mishka_developer_tools it shows me:

00:14:26.602 [notice] Application mishka_developer_tools exited: :stopped

I think, all the state of this app after I run this function is gone. Without stop, I can not update a full project, not a module!!

I think I need to solve this problem at first, how to update a dependency which is in Application.loaded_applications, actually now I first delete it and load again

Do you suggestion?

I am no families enough with Erlang, but I found this post:
https://www.erlang.org/doc/design_principles/release_handling.html#release-upgrade-file

So could not test it

shahryarjb

shahryarjb

By the way, I found this article in the following comment: https://stackoverflow.com/questions/36196148/elixir-how-can-i-leverage-release-handler

And I have read the release section of “Designing for Scalability with Erlang/OTP: Implement Robust, Fault-Tolerant Systems” book.

I am not sure, but I think using release for installing multi version of dep is not going to work perfectly in elixir, or I could not use it!! :pensive:

Hot Code Upgrades mix release — Mix v1.19.5

Erlang and Elixir are sometimes known for the capability of upgrading a node that is running in production without shutting down that node. However, this feature is not supported out of the box by Elixir releases.

Where Next?

Popular in Questions Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
logicmason
Hi there, I'm working through my first release with elixir/phoenix. I've built a release with distillery and found that it crashes when I...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
idi527
I’ve been re-reading swift book again and noticed that multiline strings there don’t have a trailing line break, unlike in elixir iex(2)...
New

Other popular topics Top

yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement