Hot code reloading is really amazing in Erlang. We use it to patch a method without restarting on a regular basis. Getting reltool properly configured to deploy the new version of your application though is a MAJOR pain in the ass. for the non-erlangers: the 'simple' way (ie i have a tiny change i want to make, so i'll just ssh in and do it) is to just edit your code, then attach to an existing node, and do make:all(…
Could you talk a little bit about what happens to processes which are running different versions of the code? Do you make your code backward compatible so that old processes continue to work with the new process? Or do you just let the old processes crash?
Do messages get lost when Erlang modules are upgraded?
21–30 of 37 posts
Re: Do messages get lost when Erlang modules are upgraded?
#22Earlier quoted context omitted.
How? You have a C++ or Java object instance running in a process how do you upgrade that code without restarting the process?
I imagine you would do what erlang does for you, just manually - isolate individual server instances, do the update, then make them public again. Say for example you are updating code in your service's web-tier. Have your LBs not send any more new traffic to the server instance, wait some reasonable length of time until existing connections are completed, deploy, restart, give LBs the A-OK to start traffic up again.…
How do you hotswap with data held in the stack or the heap? Even more if two part of your code need updated instance data, how does it ensure that update is synchronous or happens in the right order? In Java they have a $transformer() method. Ok how do you regulate the order in which $transformer() gets called. Otherwise a new version of one instance will call an old version of another.
I am not saying it is impossible to do it, there might be a way, but it is just usually working against the framework and against the default setup of the system.
Re: Do messages get lost when Erlang modules are upgraded?
#23I was a little confused by the title as it implied a relationship between a process's message box and some module which is not the case. The article does at least demonstrate that processes can transition between two versions of the same code w/o resetting state, which is, at its core, the very thing that makes code upgrades remotely practical. Other comments mention some more sophisticated machinery like release upg…
In a prod env, how do you make sure that different versions of your code coexist peacefully?
Re: Do messages get lost when Erlang modules are upgraded?
#24Earlier quoted context omitted.
Could you talk a little bit about what happens to processes which are running different versions of the code? Do you make your code backward compatible so that old processes continue to work with the new process? Or do you just let the old processes crash?
You can upgrade state in many cases if the changes are trivial, though depending on the ephemerality of a process you might let it finish or crash and restart instead of doing this.
Re: Do messages get lost when Erlang modules are upgraded?
#25Hot code reloading is really amazing in Erlang. We use it to patch a method without restarting on a regular basis. Getting reltool properly configured to deploy the new version of your application though is a MAJOR pain in the ass. for the non-erlangers: the 'simple' way (ie i have a tiny change i want to make, so i'll just ssh in and do it) is to just edit your code, then attach to an existing node, and do make:all(…
Could you talk a little bit about what happens to processes which are running different versions of the code? Do you make your code backward compatible so that old processes continue to work with the new process? Or do you just let the old processes crash?
Re: Do messages get lost when Erlang modules are upgraded?
#26Earlier quoted context omitted.
Wouldn't a reliable message queue + a script execution engine be enough?
How would a "reliable message queue + a script engine" be equivalent to a dynamically hot swappable code reloading? Could you elaborate?
Re: Do messages get lost when Erlang modules are upgraded?
#27Earlier quoted context omitted.
You can upgrade state in many cases if the changes are trivial, though depending on the ephemerality of a process you might let it finish or crash and restart instead of doing this.
So, in the worst case, for achieving basic code reloading in other erlang like systems(ex.- cloud haskell), we could let every process in the cluster crash and restart with the new version?
On the code state upgrade side there are usually a few different issues that can arise and I'd be very curious to hear if there are ways Haskell would handle some of these.
The first one is type changes. I might have a record that has a new field added. Now it's not necessarily pretty to upgrade on call with a pattern match or using a code upgrade protocol but it's easily expressed dynamically.
Another is in the interface, like adding new arguments or changing from a synchronous call to an asynchronous one. These are a bit easier to handle via indirection though they show that you'll need to plan your entry/exit points for upgrades carefully (again, OTP has things like gen_server which make this much easier).
If Haskell can manage to get past they type boundary issue then it's really a matter of supporting at least 2 simultaneous versions of code so each process can be scheduled and upgraded in natural course. Handling more than 2 could be of use depending on how aggressively you want to purge, for example, a local rather than fully qualified call can be caught in a closure and passed around as in some value to be called later. These long lived references will need to be handled carefully or you might get some delayed surprises.
Re: Do messages get lost when Erlang modules are upgraded?
#28I was a little confused by the title as it implied a relationship between a process's message box and some module which is not the case. The article does at least demonstrate that processes can transition between two versions of the same code w/o resetting state, which is, at its core, the very thing that makes code upgrades remotely practical. Other comments mention some more sophisticated machinery like release upg…
The title is confusing! It should have been "Do messages get lost during code reloading in erlang?" In a prod env, how do you make sure that different versions of your code coexist peacefully?
In terms of correctness, I'm not aware of any work that does type checking or serious analysis across version upgrades. Even Erlang's dialyzer will only check each version in isolation. So in practice this means you either test the upgrades with things like continuous integration or even manually, OR do so in very careful and small steps that are easy to reason about locally (very useful for critical applications that can't spare downtime).
Re: Do messages get lost when Erlang modules are upgraded?
#29I was a little confused by the title as it implied a relationship between a process's message box and some module which is not the case. The article does at least demonstrate that processes can transition between two versions of the same code w/o resetting state, which is, at its core, the very thing that makes code upgrades remotely practical. Other comments mention some more sophisticated machinery like release upg…
The title is confusing! It should have been "Do messages get lost during code reloading in erlang?" In a prod env, how do you make sure that different versions of your code coexist peacefully?
Easy hot code reloading is one of the great benefits from CSP.
Re: Do messages get lost when Erlang modules are upgraded?
#30Hot code reloading is really amazing in Erlang. We use it to patch a method without restarting on a regular basis. Getting reltool properly configured to deploy the new version of your application though is a MAJOR pain in the ass. for the non-erlangers: the 'simple' way (ie i have a tiny change i want to make, so i'll just ssh in and do it) is to just edit your code, then attach to an existing node, and do make:all(…
Could you talk a little bit about what happens to processes which are running different versions of the code? Do you make your code backward compatible so that old processes continue to work with the new process? Or do you just let the old processes crash?
The gen_server itself passes its module name to sys:handle_system_msg[2] when it receives a system message like a code-change notification, which ends up being the Module:Function type of call that always refers to the new version of the module, so it always ends up running the latest version when you upgrade gen_server.
[1] http://www.erlang.org/doc/man/gen_server.html#Module:init-1
[2]file:///C:/Program%20Files/erl5.9.1/lib/stdlib-1.18.1/doc/html/sys.html#handle_system_msg-6