/usr/local/CPAN/POE-Component-PluginManager/SomeApp/Plugins/example.pm
package SomeApp::Plugins::example;
use strict; # always
use warnings;
use POE; # just for the constants
our $name = "SomeApp::Plugins::example"; # the name, has to match the classname
our $longname = "example plugin that demonstrates how to write plugins."; # something descriptive
our $license = "GPL"; # the license
our $VERSION = "0.1"; # the version
our $author = 'whoppix <elektronenvolt@quantentunnel.de>'; # the author
my $pluginmanager; # the pluginmanager object. used to report errors.
my $shutdown_reason; # the reason to shut down, for simplicty stored in a global.
sub new {
my $type = shift;
$pluginmanager = shift;
my $init_data = shift; # data that can be given as parameter when loading the plugin
POE::Session->create(
'inline_states' => {
'_start' => \&start,
'_stop' => \&stop,
'sig_DIE' => \&handle_die,
'shutdown' => \&plugin_shutdown,
},
) or die '[$name] Failed to spawn a new session.';
# in this example we are spawning a new session straightforward.
# theres no problem for a plugin to have multiple sessions running,
# but the first session to start is treated by the pluginmanager as
# the 'plugin'-session, so the best way is propably to spawn an
# initial 'manager' session, and spawn more sessions from there.
}
sub start {
$_[KERNEL]->sig( DIE => 'sig_DIE' );
# this is an important thing to do. Plugins can terminate the entire
# application, if they want to, but you should do this, to make sure
# you don't crash the application by accident. For more information
# on how this works, see POE::Kernel, section "exception handling"
$_[KERNEL]->alias_set($name);
# setting an alias to keep the session alive
return [ $name, $longname, $license, $VERSION, $author ];
# this has to be returned in this order! The plugin manager catches
# the '_child' signal, and puts those values you specify here into
# the plugin table. If you fail to provide all of those values, the
# pluginmanager will send a warning about missing initial parameters.
}
sub stop {
print "[$name] is unloaded.\n";
return $shutdown_reason;
# if you care about letting the pluginmanger know why you shut down,
# this is the place to return it.
}
sub handle_die {
# called when you die.
print "[$name] plugin died\n";
my ( $sig, $ex ) = @_[ ARG0, ARG1 ];
# $sig is the signal (DIE), $ex is the exception hash (see POE::Kernel,
# 'exception handling)
$pluginmanager->error($ex);
# if you want to let the pluginmanager know that an error ocurred.
$_[KERNEL]->yield( 'shutdown', 'immediate', 'exception ocurred: plugin has to terminate.' );
# if the error is so grave, that your plugin can't continue operating norm-
# ally, shut yourself down, with an exception error.
$_[KERNEL]->sig_handled();
# if you don't do this, the application will terminate.
}
sub plugin_shutdown {
my $timing = $_[ARG0];
# timing can be "immediate", "smart" or "lazy".
# this is just a convention, here an explanation how to handle timings:
# immediate:
# shut down immediately, as fast as possible.
# smart:
# its up to you to decide what work you think is needed to be done before
# shutting down. Do everything needed, but don't do too much.
# lazy:
# lazy means you have plenty of time to shut down. This means you are
# allowed spending time on f.ex. saving your time to a database, making
# an integrity check, and make a general cleanup.
# The pluginmanager will wait while all plugins shut down, and keep the app
# up to date about how many plugins are pending, before the pluginmanager
# can shutdown.
# If the application didn't specify any shutdown timing, the default will
# be "smart".
my $message = $_[ARG1];
# shutdown message, some string, most likely not interesting.
# can be used as shutdown reason when session stops. Not guaranteed
# to be meaningfull / defined.
print "[$name] received shutdown signal: $timing because of: $message\n";
$shutdown_reason = $message;
$_[KERNEL]->alias_remove($name);
# here you need to do everything needed to make your POE::Session stop.
# here were just removing an alias, cleanly stopping the session could also
# include f.ex. stopping spawned child-sessions, unregistering to other
# sessions you registered too, and decreasing refcounts.
}
return 1;