Subject: | POE / IKC / signals / cookbook failure on Win32 |
The attached files are the IKC app server and client from the cookbook
(http://poe.perl.org/?POE_Cookbook/Application_Servers_2). The client
is unchanged, the server has had a "pulse" event added.
If I call "pulse" at regular intervals using delay the script exits on
ctrl-C. Otherwise the script spins the CPU on ctrl-C.
Possibly this is an IKC or cookbook bug.
Subject: | client.pl |
#!/usr/bin/perl
use warnings;
use strict;
use POE::Component::IKC::ClientLite;
# Create an IKC client. This also establishes a connection to an IKC
# server. Part of the registration process is choosing a unique name
# for ourselves, which we do naively by abusing the process ID.
my $name = "Client$$";
my $remote = create_ikc_client(
port => 31338,
name => $name,
timeout => 10,
);
die $POE::Component::IKC::ClientLite::error unless $remote;
# We want the server to add up a list of numbers. Using
# post_return(), we can send a detached event to the server and wait
# for its response. The response can be delayed up to the
# create_ikc_client() timeout. post_return() returns the value that
# was posted back to us from service_response() in the corresponding
# server example.
my @numbers = qw(8 6 7 5 3 0 9);
print "Summing : @numbers\n";
my $return_value = $remote->post_respond('application/calc_sum', \@numbers);
die $POE::Component::IKC::ClientLite::error unless defined $return_value;
print "The sum is: $return_value\n";
exit 0;
Subject: | server.pl |
#!/usr/bin/perl
use warnings;
use strict;
use POE qw(Session);
use POE::Component::IKC::Server;
use POE::Component::IKC::Specifier;
# Create an IKC server. It runs as a separate session, and does
# message passing for us.
POE::Component::IKC::Server->spawn(
port => 31338,
name => 'AppServer',
);
# Create a session that will be accessible through an IKC network.
POE::Session->create(
inline_states => {
_start => \&service_start,
calc_sum => \&service_calc_sum,
did_something => \&service_response,
pulse => \&NO_OP,
}
);
# Run, server, run!
POE::Kernel->run();
exit 0;
# Start the service. Set up an alias, which is our service's name.
# Call IKC to publish the service and some public events.
sub service_start {
my ($kernel, $heap) = @_[KERNEL, HEAP];
my $service_name = "application";
$kernel->alias_set($service_name);
$kernel->call(IKC => publish => $service_name, ["calc_sum"]);
# With this ctrl-C exits. With out this CPU spins near 100% on ctrl-C.
$_[KERNEL]->delay(pulse => 1);
}
# Calculate the sum of the numbers in a list. We only perform minimal
# data validation here, which may be a hazard in a real application.
#
# This service is intended for use with PoCo::IKC::ClientLite's
# post_respond() method. Therefore ARG0 is special: the data given to
# us is in element 0, and an RSVP identifier is in element 1. Posting
# the response to the RSVP identifier will send it back to the
# requester.
#
# However, we don't send the sum back right away. Instead, we delay a
# little bit to show how you can pass data through the usual POE event
# handlers before sending it back.
sub service_calc_sum {
my ($kernel, $heap, $request) = @_[KERNEL, HEAP, ARG0];
my ($data, $rsvp) = @$request;
my $sum = 0;
if (ref($data) eq "ARRAY") {
$sum += $_ foreach @$data;
}
#$kernel->delay_set(did_something => 1, $rsvp, $sum);
$kernel->yield(did_something => $rsvp, $sum);
}
# After a little time, send the response back. We post the response
# to the RSVP identifier. IKC matches it up to the client internally.
sub service_response {
my ($kernel, $heap, $rsvp, $sum) = @_[KERNEL, HEAP, ARG0, ARG1];
$kernel->call(IKC => post => $rsvp, $sum);
}
sub NO_OP {
warn "NO_OP\n";
$_[KERNEL]->delay(pulse => 1);
}