On Sep 29, 2008, at 13:12, Seth Daniel wrote:

On Sat, Sep 27, 2008 at 11:45:57PM +0200, Martijn van Beers wrote:
On Sat, 2008-09-27 at 14:16 -0700, Seth Daniel wrote:
Hi,

Once the child session performs a put(), the write will fail and I
receive an ErrorEvent. I don't seem to be able to get the data that was in the original put(). So, if I buffer the data, perform the put(), and then receive an error I can use the wheel_id to identify the data that failed to be written. However, I don't get an event when the write is successful so it doesn't seem like I can remove items from the buffer.

You can sign up for Wheel::ReadWrite's FlushedEvent, just like you had
to to receive the ErrorEvent.

This seems to work well, but only if I have a new ReadWrite wheel for
each write (my initial plan was to have a single ReadWrite wheel for the
lifetime of the session).  This way the write queue is guaranteed to
either be flushed or have an error.  I can also use a ReadWrite wheel
for some set amount of writes and then expire the wheel. This saves me from having to potentially create millions of ReadWrite wheels over the
lifetime of the server.

So buffering the data to be written and expiring ReadWrite objects works pretty well. My only question would be: is this really the best way to
'retry' writes?  Seems like there should be an easier way.

I would do it differently. I'd use a flag to busy out the connection until I received positive acknowledgment of transmission or an error:

1. On put(), set a "busy" flag. Don't use the connection while it's busy. 2. On FlushedEvent, clear the "busy" flag, and poll for another transaction to be sent. 3. On ErrorEvent, push the failed transaction back into the queue, and recycle the connection.

By the way, you don't need one session per POE::Wheel::ReadWrite object. A single session can maintain a hash of ReadWrite wheels, keyed on wheel ID. The single session can then manage connections more directly, cleanly and with less overhead. For example, you don't need to post() messages within the application before transmitting them on the wire.

I orignally considered introspecting into POE::Driver::SysRW's output buffer, but this doesn't really solve anything. You can't reliably reuse the buffered data for at least two reasons: First, all type information is lost, so you can't be sure what it contains (but you can probably guess or assume, since it's your application). Second, and much worse: The data may have been partly written, so it may not be reusable. For example, a large HTTP upload may have been interrupted; retrying would fail as the headers are no longer in the buffer.

--
Rocco Caputo - [EMAIL PROTECTED]

Reply via email to