[erlang-questions] On upgrading
Sat Mar 30 23:17:26 CET 2013
On Saturday, March 30, Jonathan Schneider wrote:
> soft_purge/1 must know at some level which processes are still
> running the old version of a module. Does this function have a
> friend that returns a list of identifiers of processes that are
> getting in the way (that would die in a subsequent module load) ?
The closest I know of is erlang:check_process_code(Pid, Module). Here's
a one-liner which does what you want, in this case for the 'io' module:
lists:filter(fun(P) -> erlang:check_process_code(P, io) end, erlang:processes()).
> The problem case is where a process has called through the module
> that wants upgrading and can't easily be tickled to let go of
> it. Obviously one would try not to have code arranged like that.
Exactly. Don't do that.
> Would it be possible to support not one but arbitrary old versions
> of modules?
Probably a bunch of work.
For well-behaved code, e.g. a gen_server, having arbitrary old
versions (AOV) won't make a difference; you'll only ever run
old code for a very short time.
One case where AOV would make a difference: code which which is
"eventually" well-behaved. Imagine a process blocked in
gen_tcp:accept/1. You've loaded debug code into a live system and now
want to re-load the regular code and go home, but can't until the next
TCP connect happens. A pragmatic way out of this example is to
generate a TCP connect. There are other examples where you can't do
that, e.g. code blocked in gen_tcp:recv/2.
With AOV, such a system will drop from running three versions of the
code to two, and then back to one. But that's not clearly better than
going home after starting something like:
case code:soft_purge(my_module) of
true -> load_new_code();
false -> wait_and_hope()
Maybe someone has a more compelling real-world example.
More information about the erlang-questions