Hi all.
I am very new to POE.
I need to create a service which would accept HTTP GET requests, retrieve file names from them and run two long processes on these files.
Other application is assumed to upload the files and send HTTP GET requests to my service.
I have borrowed the example from here: http://www.perlmonks.org/index.pl?node_id=709022
I use POE::Component::Server::HTTPServer, POE::Component::JobQueue and POE::Wheel::Run::Win32
The problem is that my service processes only the number of requests, specified in the WorkerLimit parameter of POE::Component::JobQueue->new.
For all other requests, I see only prints from HTTP handlers, Wheel::Run is not running.
Here is the code:
#!perl.exe
use warnings;
use POE qw( Wheel::Run::Win32 Filter::Line);
use POE::Component::Server::HTTPServer;
use POE::Component::Server::HTTPServer::Handler;
use POE::Component::JobQueue;
use POE::Filter::Reference;
use File::Basename;
use Data::Dump qw(dump);
my $port=8080;
my $max_tasks=3;
sub _start {
my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
$heap->{child2} = POE::Component::Server::HTTPServer->new(
port=>$port,
handlers => [ "/add" => \&add_task,
"/" => \&root_handler
]
);
$heap->{child2}->create_server();
POE::Component::JobQueue->spawn
( Alias => 'passive',
WorkerLimit => $max_tasks,
Worker => \&make_a_worker,
Passive => { }
);}
# =========== HTTP handlers ========
sub root_handler {
my $context = shift;
print "\nroot_handler ===request===\n";
print "root_handler: uri: ",$context->{request}->uri,"\n";
$context->{response}->code(200);
$context->{response}->content(
"<HTML><BODY><H1>Hi There</H1></BODY></HTML>\n"
);
return H_FINAL;
}
sub add_task {
my $context = shift;
print "\nadd_task ===request===\n";
print "add_task uri: ", $context->{request}->uri,"\n";
$context->{request}->uri=~/\/add\?(.*)/;
my @job_params=($1);
POE::Kernel->post( 'passive',
'enqueue',
'postback',
@job_params
);
$context->{response}->code(200);
$context->{response}->content(
"<HTML><BODY><H1>add task ".join(" ",@job_params)." </
+H1></BODY></HTML>\n"
);
return H_FINAL;
}
# =========== JobQueue handlers ========
sub make_a_worker {
my ($postback, $message) = @_;
POE::Session->create(
inline_states => {
_start => \&worker_start,
worker_child_stdout => \&worker_child_stdout,
worker_closed => \&worker_closed,
sig_child => \&sig_child
},
args => [ @_ ]
);
}
sub worker_start
{
my ($kernel, $session, $heap, @args ) = @_[KERNEL, SESSION, HEAP,
+ARG0 .. $#_];
$heap->{postback}=$args[0];
$heap->{message} =$args[1]; # file name
$heap->{SessionID} = $session->ID;
print " -start_message_process: ".$heap->{SessionID}."\n";
my @ffmpeg_args=("-y","-i","<input mpeg>","-acodec","pcm_s16le","-
+ar","16000","-ab","16000","-ac","1","<output wav>");
$ffmpeg_args[2] =$args[1];
my ($name,$path,$suffix) = fileparse($args[1],(".mpg"));
$ffmpeg_args[11]="$path\\$name.wav";
$heap->{stage}="ffmpeg";
$heap->{cmdlinefish} = POE::Wheel::Run::Win32->new(
Program => "ffmpeg",
ProgramArgs => \@ffmpeg_args,
StdoutEvent => "worker_child_stdout",
StderrEvent => "worker_child_stdout",
CloseEvent => "worker_closed",
StdioFilter => POE::Filter::Line->new(), # Child speaks in
+ lines.
StderrFilter => POE::Filter::Line->new(), # Child speaks in
+ lines.
);
}
sub worker_child_stdout
{
my ( $heap, $preargs ) = @_[ HEAP, ARG0 ];
print "-worker_child: session ",$heap->{SessionID}," ",$preargs,"\
+n";
$heap->{results}=$preargs;
}
sub worker_closed
{
my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
my $postback=$heap->{postback};
my $results=$heap->{results};
if($heap->{stage} eq "ffmpeg") {
if($results =~ /video:\d+kB audio:(\d+)kB global headers:\d+kB
+/) {
$results = ($1>0)?"Ok":"fail";
}else{
$results = "fail";
}
} else {
}
$postback->(($results));
print "-worker_closed: $results\n";
}
sub sig_child
{
my ( $heap, $sig, $pid, $exit_val ) = @_[ HEAP, ARG0, ARG1, ARG2 ]
+;
my $details = delete $heap->{cmdlinefish};
print " -sig_child\n";
return 0;
}
# ==========
my @handlers = qw(
_start make_a_worker
);
# worker_start worker_child_stdout worker_closed root_handler add_task
POE::Session->create( package_states => [ main => \@handlers ] );
POE::Kernel->run();
exit 0;
__END__
So, this service successfully processes 3 files.
Then I see only messages "add_task: uri:/add?file/name", and no output from ffmpeg.
Looks like the wheels don't exit.
Another question. Currently, I have partially implemented only the first processing stage (call to ffmpeg to extract an audio stream from a video clip).
I would appreciate advices on how to run the second executable, which would process the produced wav file.
Update
I've overcome the first problem.
Just added
my $details = delete $heap->{cmdlinefish};
in the end of worker_closed, before call to postback.
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.