App-MultiModule
view release on metacpan or search on metacpan
lib/App/MultiModule/Tutorial.pod view on Meta::CPAN
}
sub set_config {
#optional, but usually necessary to do useful stuff.
#This is called when a task receives config, and is the only
#way a task can do any necessary setup in order to produce
#messages.
#Also note that set_config() is called every time config
#changes. Code in this method must not assume only a single
#invocation.
my $self = shift;
#as in message()
my $config = shift;
#this argument always comes in as a HASH reference
my %args = @_;
#as in message()
$self->{config} = $config;
#not necessary in this example, but is a common pattern
#if future calls to message() need access to config
$self->{state} = { ct => 0 } unless $self->{state};
#Initialize our counter, but only the first time. This task is
#marked as 'stateful' (see the code below), so after we are first
#run, future runs (between restarts and crashes) will have
#$self->{state} already 'filled in'.
$self->named_recur(
#perldoc App::MultiModule::Core
#this method schedules the passed CODE reference to be run
#on the specified interval
recur_name => 'Example1',
#this string is the process global uniqueness identifier;
#that is, given that set_config() can be called any number
#of times, named_recur(), with a unique recur_name field,
#will schedule the repeating call to the passed CODE ref
#only once.
repeat_interval => 1,
#how often to run, in seconds.
work => sub { #What we're going to do on an interval
my $message = {
#a 'message' is nothing special, except it must
#always be a HASH reference at the top level
ct => $self->{state}->{ct}++,
#increment the counter in the saved state, and
#put that into the 'ct' field of the message.
outstr => $config->{outstr},
#simply pass in the configured 'output' string.
};
$self->emit($message);
#key point!
#Tasks do not send messages to other tasks. They simply
#emit() messages to the MultiModule framework. Separate
#config to the Router task is fully responsible for how
#messages flow.
},
);
}
#tasks default to not stateful; in order to become stateful, just
#make the is_stateful() method return some kind of true thing
sub is_stateful {
return 'yes!';
}
1;
=head2 Example2
This task will be the 'consumer': it will receive the produced
messages and output the counter and output string.
Here is the source:
package MultiModuleTest::Example2;
use strict;use warnings;
use parent 'App::MultiModule::Task';
sub message {
my $self = shift; my $message = shift;
if($message->{ct} and $message->{outstr}) {
#defensive programming here; it is best not to assume that
#every message we get has the fields we expect.
print STDERR "Example2: received a message: $message->{ct} ($message->{outstr})\n"
#just output the counter and output string
}
}
#note what's missing: this task doesn't need any config, and
#it needs no state handling.
1;
=head1 The Config
Place this in a file named 'test.conf' in the directory where
you are running this tutorial.
Simply put, the task name is the HASH key, and the value is the
configuration sent to that task. It's really that simple.
Here it is:
{ Example1 => { #this HASH reference is passed as the
#second argument (after $self) to
#the set_config() method, as illustrated
#above
outstr => 'howdy'
},
Router => { #Just skim over this config, then read the
#detailed description below. Then re-read
#this config, and it'll make sense.
( run in 0.711 second using v1.01-cache-2.11-cpan-df04353d9ac )