http://qs1969.pair.com?node_id=895643

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Is it possible to add extra code to a running Perl program without stopping it. Basically Im looking at a situation where it will be possible to avoid downtime. I know this is a ridiculous demand. The problem is basically the client for which I work has elaborate processes for even killing processes even in test environment. Providing endless justifications to unfriendly people is a little difficult.It will be nice if there is way to do the modifications without killing the running processes.

I've heard few languages already have this feature. Is it possible to add or modify existing Perl code of a running program without stopping it.

  • Comment on Adding code to a Perl program without stopping it

Replies are listed 'Best First'.
Re: Adding code to a Perl program without stopping it
by GrandFather (Saint) on Mar 26, 2011 at 08:31 UTC

    Yes. Specifically it is possible to reload a module. The trick is to update %INC so that a subsequent call to require reloads the module. Consider:

    # reload.pl use strict; use warnings; for (1 .. 2) { delete $INC{'ReloadModule.pm'}; require ReloadModule; for (1 .. 3) { print ReloadModule::nextCount(), " "; } print "\n"; } # ReloadModule.pm use strict; use warnings; no warnings 'redefine'; package ReloadModule; my $count = 0; sub nextCount { return ++$count; } 1;

    Prints:

    1 2 3 1 2 3

    Note the use of no warnings 'redefine'; in the module to be reloaded to suppress "Subroutine nextCount redefined at ..." warnings.

    True laziness is hard work
Re: Adding code to a Perl program without stopping it
by Corion (Patriarch) on Mar 26, 2011 at 09:10 UTC

    Also see eval, if you want to add new code without even having a file, and DBIx::VersionedSubs for how to load code from a database, where an update to the database also changes the code that will be run.

Re: Adding code to a Perl program without stopping it
by Anonymous Monk on Mar 26, 2011 at 08:06 UTC

      Module::Reload->check() basically does:

      • delete $INC{module_name};
      • require 'module_name' ;

      but only if the modified_time of the package has changed on disk, which is very nice, Module::Reload works properly.

      However, what if you delete a sub from a module while running the program, the function will remain loaded. That needs to be fixed in Module::Pluggable.

      I took a look at Apache::StatINC and it does the same as Module::Reload except it does delete the subs that are gone using this:

      • $class->Apache::Symbol::undef_functions( undef, 1 );

      However, I guess Apache::StatINC can be use only if you're writing a web app deployed using Apache. What if you want to write a non-web app(an IRC bot for example) ?

      Plack::Loader::Shotgun I wasn't able to check out because I'm not familiar with Plack

Re: Adding code to a Perl program without stopping it
by TomDLux (Vicar) on Mar 27, 2011 at 16:40 UTC

    If you're running on Unix, you can send a signal (kill) which your process catches. The signal handler reads a file which contains a list of modules and versions which should be loaded, and compares those with what actually is loaded, and loads / reloads the missing ones.

    On the other hand, loading your whiz-bang "Divide-by-zero" module is little benefit if there are no calls to it.

    As Occam said: Entia non sunt multiplicanda praeter necessitatem.

      if there are no calls to it

      which is why when you use the delete $INC{...}/require technique you generally either only update a set of known volotile modules, or you use a registration processes with a known entry point in the modules.

      I use the registration technique to add new task handlers to a distributed task handling system that provides automated build and testing services. It allows me to add or correct task handlers without restarting (currently) six systems.

      True laziness is hard work