While you wait for someone to post a POE solution (could take a while), you might get away with something as simple as this:
#! perl -slw
use strict;
use IO::Socket;
use IO::Select;
use threads;
use threads::shared;
use Thread::Queue;
my $done :shared = 0;
my $Qin = new Thread::Queue;
my $Qout = new Thread::Queue;
sub listener {
my %conns;
my $listener = IO::Socket::INET->new(
LocalAddr => 'localhost:54321', Listen => 10, Reuse => 1
) or die "Failed to create listener: $!";
my $sel = new IO::Select( $listener );
until( $done ) {
if( $sel->can_read( 0.01 ) ) {
my $client = $listener->accept;
$conns{ $client } = $client;
my $req = <$client>; ## Assumes request is a single line
$Qin->enqueue( "$client : $req" );
warn "Accepted and queued request '$req'";
}
elsif( $Qout->pending ) {
my( $client, $res ) = split ' : ', $Qout->dequeue, 2;
print { $conns{ $client } } $res;
close $conns{ $client };
delete $conns{ $client };
}
}
close $listener;
}
my $lt = threads->create( \&listener );
while( my( $client, $req ) = split ' : ', $Qin->dequeue, 2 ) {
async{
my $serv = IO::Socket::INET->new( 'localhost:12345' );
print $serv $req;
warn "dequeue and forwarded '$req'";
my $res = <$serv>;
warn "Retrieved and queued '$res'";
$Qout->enqueue( "$client : $res" );
close $serv;
}->detach;
select '','','', 0.1; ## Ensure no more than 10/s
}
This creates 2 threads. The listener thread, which accepts connections, maintains a (non-shared) hash of client sockets and queues the requests as they are recieved. Then the main thread dequeues the requests, spawns a thread to forward that request and await the reply before queing that back to the listener thread. A 1/10 second delay in the second threads processing loop ensures the request rate doesn't exceed 10/second. When the spawned threads receive their replies, they are queued back to the listener thread for dispatch back to the appropriate socket.
Of course, a thread pool solution for the upstream connections might be more efficient (as well as a tad more complicated), but whether that is necessary depends a lot upon the burst rate of your PE process?
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.