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
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:
- The GenServer has no custom implementation of
code_change/3which 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. - 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 customcode_change/3s for their servers. - The GenServer has a custom implementation of
code_change/3which 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
You do not need to stop an application first before upgrading it.
Maybe I am misunderstanding what you’re trying to accomplish?
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.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









