Thread::App::Shutdown - a singleton to manage shutdown of a threaded application
use Thread::App::Shutdown; my $shutdown = Thread::App::Shutdown->instance; my $transactions = 0; while( 1 ) { last if $shutdown->get(); # do something monumentous if( ++$transactions > 1000 ) { $shutdown->set(); } }
*** A note of CAUTION *** This module only functions on Perl version 5.8.0 and later. And then only when threads are enabled with -Dusethreads. It is of no use with any version of Perl before 5.8.0 or without threads enabled. *************************
Thread::App::Shutdown provides a singleton that can be used by multiple threads to coordinate the clean shutdown of a threaded application.
In a large threaded application, you might have one or more pools of worker threads plus a coordination thread, a thread receiving signals and a dedicated thread feeding input from some external source into the worker pool(s). When some predefined event happens (SIGTERM received, a particular type of input is received, x number of transactions have been processed by the worker pool, etc.), the application should shut down.
To effect this, you can create a shared variable for each of the event types and pass references to the variable to all of the discrete program units, or you can break with OO and have a single shared global variable that all program units look at as $main::shutdown or $Foo::shutdown.
Thread::App::Shutdown makes the second option cleaner. Anywhere in the program that the shutdown state has to be set or queried, simply retrieve an instance of Thread::App::Shutdown and call it's methods.
Because Thread::App::Shutdown is a singleton, you don't construct it with ->new(). To get a copy of the one and only object, use the ->instance() accessor.
->new()
->instance()
If an instance of the class does not already exist, one will be created and returned. All subsequent uses of ->instance will return the same object. As such, it is important that the first instance of the Thread::App::Shutdown object be created prior to any other threads. Typically you would get the instance as part of the program initialization.
->instance
The set() method sets the flag to indicate that shutdown is pending. It returns the previous value of the shutdown flag.
The get() method returns a true value or undef to indicate whether the shutdown flag is set or not.
my $shutdown = Thread::App::Shutdown->instance; lives_ok { $shutdown->set( 1 ) } 'set flag to 1'; is( $shutdown->get, 1, 'flag is set');
The clear() method resets the shutdown flag to indicate that shutdown is not pending. It also returns the previous value of the shutdown flag.
In your main program:
use threads; use Thread::App::Shutdown; my $shutdown = Thread::App::Shutdown->instance; my $foo = Foo->new; my $thread = $foo->run; $SIG{TERM} = sub { $shutdown->set }; $thread->join;
In Foo.pm:
package Foo; use threads; use Thread::App::Shutdown; sub new { bless {}, $_[0] } sub run { my $shutdown = Thread::App::Shutdown->new; return threads->create( sub { while( 1 ) { last if( $shutdown->get ); print "no shutdown yet\n"; sleep(10); } } ); } 1;
This example is likely to work only on thread implementations that use pseudo-processes. On other thread implementations, POSIX::SigAction has to be used to ensure that only the main thread receives SIGTERM.
threads & threads::shared
Thread::SigHandler
Thread::Signal by Elizabeth Mattijsen.
James FitzGibbon, <jfitz@CPAN.org>
Copyright (c) 2003 James FitzGibbon. All Rights Reserved.
This module is free software; you may use it under the same terms as Perl itself.
To install Thread::App::Shutdown, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Thread::App::Shutdown
CPAN shell
perl -MCPAN -e shell install Thread::App::Shutdown
For more information on module installation, please visit the detailed CPAN module installation guide.