On Tue, Dec 10, 2002 at 02:03:33PM -0200, Cristiano Lincoln Mattos wrote:
> 
>       If a client quickly sends 15 or so messages and then closes
> the connection, my POE script has by this time just gotten the
> ReadWrite InputEvent for message number 8 or so, and is still
> lagging behind processing them.  That wouldn't be such a problem,
> but then the ErrorEvent for the wheel gets notified (because of the
> closed connection), and there i detect that the connection has been
> closed (function is read and errnum is 0) and shutdown the wheel.
> So I end up reading around 8 messages of the 15 that were sent,
> because the ErrorEvent is being kicked in before all of the fifteen
> InputEvent's.
> 
>       The remaining InputEvent's are probably in some dispatch queue
> inside POE, because the socket's already been closed, and all the
> data from it has been read.  When i kill the Wheel in the "early"
> ErrorEvent, those remaining InputEvents are discarded without being
> delivered to my session..
> 
>       Is there any way out of this, without having to redesign the
> protocol to include flow control or EOTs (I cant change the client)?
> I tried using pause_input() and resume_input(), but without success.
> Correct me if I'm wrong, but if there was a way to see if there are
> any pending events (more specifically, InputEvents) to be received
> for a Wheel, I could check this out in the ErrorEvent, and only
> close the Wheel when all the InputEvents have been received.
> 
>       Im using ActiveState perl 5.6.1 on a Windows 2K PRO system,
> with POE version 0.23.  Thanks for any help.

I've been looking at _define_read_state() in Wheel::ReadWrite.  I
can't determine why it would be producing the results you see.

Here's the relevant code from Wheel::ReadWrite.  It's triggered by a
select_read() event.  It calls the wheel's driver to read a chunk of
raw data.  If there's data, it's passed through the wheel's filter.
Every filtered message is then immediately passed to the InputEvent
handler.

It only calls ErrorEvent when the driver reaches EOF.  By that time,
though, all the filtered messages should have been processed in the
C<while (1)> loop.

            my ($k, $me, $handle) = @_[KERNEL, SESSION, ARG0];
            if (defined(my $raw_input = $driver->get($handle))) {
              $$input_filter->get_one_start($raw_input);
              while (1) {
                my $next_rec = $$input_filter->get_one();
                last unless @$next_rec;
                foreach my $cooked_input (@$next_rec) {
                  $k->call($me, $$event_input, $cooked_input, $unique_id);
                }
              }
            }
            else {
              $$event_error and
                $k->call( $me, $$event_error, 'read', ($!+0), $!, $unique_id );
              $k->select_read($handle);
            }

Are you using a custom filter?  Could it be possible that your filter
isn't returning everything it should?

-- Rocco Caputo - [EMAIL PROTECTED] - http://poe.perl.org/

Reply via email to