[erlang-questions] On upgrading

Matthias Lang <>
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:

  wait_and_hope() ->
    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 mailing list