App-Diskd
view release on metacpan or search on metacpan
lib/App/Diskd.pm view on Meta::CPAN
# input from the console.
# Plain input is registered with ReadLine's input history, echoed back
# to the console, and sent to the server. Exceptions, such as when
# the user presses Ctrl+C to interrupt the program, are also handled.
# POE::Wheel::ReadLine events include two parameters other than the
# usual KERNEL, HEAP, etc. The ARG0 parameter contains plain input.
# If that's undefined, then ARG1 will contain an exception.
sub console_input {
my ($heap, $input, $exception) = @_[HEAP, ARG0, ARG1];
if (defined $input) {
$heap->{cli_wheel}->addhistory($input);
# $heap->{cli_wheel}->put("You Said: $input");
$heap->{io_wheel}->put($input);
}
elsif ($exception eq 'cancel') {
$heap->{cli_wheel}->put("Canceled.");
}
else {
$heap->{cli_wheel}->put("Bye.");
delete $heap->{cli_wheel};
delete $heap->{io_wheel};
return;
}
# Prompt for the next bit of input.
$heap->{cli_wheel}->get("=> ");
}
1;
__END__
=head1 NAME
diskd - An example POE-based, peer-to-peer disk finder/announcer
=head1 SYNOPSIS
$ ./diskd -d & # run in network daemon mode
$ ./diskd # start local client
=> help # get help
=> list # show information about known disks
=> ...
=> <EOF> # ^D exits client
=head1 DESCRIPTION
This program is intended as an example of:
=over
=item 1. using multicast to send and receive data among several peers
=item 2. communicating with local clients via a Unix domain socket
=item 3. using POE to achieve both of the above
=item 4. using POE to periodically run an external program without blocking
=item 5. encapsulating a data structure that can be accessed and updated by the above
=back
The information shared between peers in this example is the list of
disks that are currently attached to each system. The "blkid" program
is used to gather this information. It reports on all disks attached,
regardless of whether the disk (or partition) is currently mounted or
not.
A copy of diskd should be run on each of the peer machines. The first
thing that it does is join a pre-defined multicast channel. The daemon
then collects the list of disks attached to the system and schedules
the collection to trigger again periodically. It also sets up a
periodic event that will send the details of the disks attached to the
machine to other peers that have joined the multicast channel. It also
listens to the channel for incoming multicast messages from another
peer and uses them to update its list of which disks are attached to
that peer. As a result of this, each daemon will be able to build up a
full list of which disks are available in the peer network and to
which machine they are attached. Thus the primary function of the
program is to be able to locate disks, no matter which machine they
are currently attached to.
The diskd program can also be run in client mode on any machine that
has a running diskd daemon. The client conencts via a local unix
domain socket and, providing the connection succeeds, it will then be
able to pass commands to the daemon. Currently the only useful command
that is implemented is 'list', which prints a list of all the disks
that the daemon knows about. More commands could be added quite
easily.
=head1 MOTIVATION/GENESIS
The reason for writing this program was to explore three key areas:
=over
=item 1. Multicast (and peer-to-peer) networking
=item 2. Daemons and method of communicating with them
=item 3. Using POE to develop a non-trivial program with a focus on asynchronous, event-based operation
=back
As I write this, the size of the program is significantly less than
1,000 lines (not including this documentation), while still managing
to implement a reasonably complex network daemon. In all, it took
about an evening's work to code and eliminate most of the major
bugs. The reason for both the small size and quick development time
can be attributed to the combination of Perl and POE. Despite this
being my first time writing any program using POE, the speed of
development was not down to amazing programming skill on my
part. Rather, it boiled down to just one factor: almost all of the POE
code I have here was based, in one way or another, on example code
hosted on the L<POE Cookbook site|http://poe.perl.org/?POE_Cookbook>.
Since I had already read up sufficiently on POE (and the examples in
the cookbook) and knew in general how I wanted my daemon to work,
selecting the relevant recipes and reworking them was a pretty
( run in 0.719 second using v1.01-cache-2.11-cpan-39bf76dae61 )