Re: Architecture advice requested

2009-06-04 Thread Rocco Caputo

On May 29, 2009, at 04:48, Ed W wrote:


Rocco Caputo wrote:


The best way to break an application into POE entities is not to.   
Decompose the application into entities and relationships that make  
sense for the application.  Determine the requirements first, then  
apply POE to fulfill them.


OK, to be specific, the heart of it is a proxy server, which seems  
to be fulfilled by using protocol X client wheel talking to protocol  
X server wheel?  The bits I guess I am most interested in are:


- How I might architect the POP server client to be one step removed  
from the socket and have the following pipeline attached to the  
socket:   data_in - decompress - parse input data into separate  
protocols and feed to correct wheel.  Is this another wheel, or done  
as a filter? (or something else?)


I might implement this in application code until I knew the  
requirements and constraints on the data_in - decompress - parse  
flow.  As those emerged (or were specified), I might refactor the  
generic transformative bits into their own modules.  The most  
significant trade-off seems to be whether reusability or throughput is  
more important.  If reusability: I would refactor the transformative  
code into POE::Filter, POE::Driver and/or POE::Wheel namespaces.  If  
throughput, I would evaluate whether custom object APIs fit the  
application better.


- Same for the output.  ie taking the output of multiple wheels,  
compressing the output and then blocking it into a simple protocol  
to multiplex over a single TCP connection (just data packet with a  
header on it)


Funneling would be done by a component (aka a module that uses  
POE).  There seems to be a lot of decision logic and the possibility  
that the funnel will respond to individual clients.  Something higher  
level must be responsible for the side effects since POE::Filter and  
POE::Wheel::ReadWrite are strictly transformative.


- The main reason for looking at POE is that while it's mostly a  
pipeline, occasionally one distinct bit of the app needs to talk to  
another distinct bit, eg some remote end hangs up suddenly, the  
client end may not be expecting this as part of it's normal protocol  
and we need to wake it up and force it to terminate the other side  
of the proxy.  Any special features of POE which would be especially  
helpful here?


It sounds like you want the client and server sides of the proxy to be  
loosely coupled.  For instance, the remote end may hang up suddenly at  
the end of a message, but the local end may still be receiving.  You  
might want to wait for the local end to finish before shutting down  
the connection.


POE can help accomplish this by making it easier to decouple the  
client and server sides of the proxy.  The proxy behavior is then  
goverend by the message protocol you define between the client and  
server, rather than by the particular protocols on either end.


Recently I've seen POE used to proxy between stateless HTTP and a  
stateful game.  The idea seems similar.  It allows an HTTP client to  
come and go, but it keeps the game connected.  It adapts the two by  
tracking the game's state in the proxy, then updating the user when  
they refresh the page.


POE doesn't have a component for mapping client and server sides of  
proxies.  If you write one, I hope you can release it.


--
Rocco Caputo - rcap...@pobox.com


Re: Bug in PoCo::Child when PID wraps round

2009-06-04 Thread Erick Calder
sorry, I still own it.  I've just been disconnected from the world a long
time.  it will take me a while to get back to you on this but I will

 From: Tony Wildish wild...@mail.cern.ch
 Date: Thu, 7 May 2009 10:58:12 +0200
 To: poe@perl.org
 Subject: Re: Bug in PoCo::Child when PID wraps round (fwd)
 
 Hi,
 
  just checking one more time: is anyone looking after PoCo::Child, or is
 it orphaned?
 
  TIA,
  Tony.
 
 On Wed, 15 Apr 2009, Tony Wildish wrote:
 
 Hi,
 
  I sent this to the bug-poe-component-ch...@rt.cpan.org list some time ago
 but it looks like that list is dead. Is there someone here managing
 PoCo::Child?
 
  Cheers,
  Tony.
 
 -- Forwarded message --
 Date: Tue, 24 Mar 2009 12:56:33 +0100 (CET)
 From: Tony Wildish wild...@mail.cern.ch
 To: bug-poe-component-ch...@rt.cpan.org
 Subject: Bug in PoCo::Child when PID wraps round
 
 Hi,
 
  we have been using PoCo::Child in a project for a while now and have just
 uncovered a bug. The internal bookkeeping for the association of wheelIDs
 and PIDs is wrong, with the result that when the OS PID wraps round, the
 wrong wheelID will be given to the 'done' event.
 
  I'm using PoCo::Child version 1.39, perl 5.8.5, kernel
 2.6.9-78.0.8.EL.cernsmp.
 
  You can see the bug by inspection of the code. At line 192 we have:
 
 my $id = $wheel-ID;
 $self-debug(qq/run(): @$cmd, wheel=$id, pid=/ . $wheel-PID);
 
 $self-{$PKG}{pids}{$wheel-PID} = $id;
 
  so the {pids} are inserted keyed on $wheel-PID. But at line 268, the
 clean up deletes as follows:
 
 delete $self-{$PKG}{wheels}{$id};
 delete $self-{$PKG}{pids}{$id};
 
  so it's deleting keyed on wheel-ID, not $wheel-PID.
 
  When the PIDs wrap round, the protection in sig_child is broken by this:
 
 sub sig_child {
 my ($kernel, $self, $pid, $rc) = @_[KERNEL, OBJECT, ARG1, ARG2];
 
 my $id = $self-{$PKG}{pids}{$pid} || ;
 
 # child death signals are issued by the OS and sent to all
 # sessions; we want to handle only our own children
 
 return unless $id;
 
  Because the {pids} hash had the wrong entry deleted in the cleanup, when
 the PIDs wrap, an old $id will be found where none should be. So sig_child
 will not return here, and will cause 'done' to be fired with the old
 wheelID, which is plainly wrong.
 
  Also, the cleanup around line 268/269 should remove {CLOSED} and
 {SIGCHLD} entries for the wheel too. That's less serious because it won't
 cause a problem until wheel-IDs wrap round, which will take a lot longer,
 but it's still a leak.
 
  Cheers,
  Tony.