Hi Philip,

I am writing since many years POE projects. One of the
first things I figured out in productive environment is to
test the poe object with defined() and ref(). I had so often
programs  running over days or weeks and then just
stopping with a "Can't  call method on undefined value",
so I today do defined() and ref() test on any POE object call.
Especially on put!

This looks for example like this:

$heap->{server}->{$wheel_id}->{wheel}->put('xyz')
if (exists <http://perldoc.perl.org/functions/exists.html>($heap->{server}->{$wheel_id}->{wheel}) && defined <http://perldoc.perl.org/functions/defined.html>($heap->{server}->{$wheel_id}->{wheel}) && (ref <http://perldoc.perl.org/functions/ref.html>($heap->{server}->{$wheel_id}->{wheel}) eq "POE::Wheel::ReadWrite"));

Much regards,
Markus Mueller
While writing http://search.cpan.org/dist/POEx-HTTP-Server/ I've discovered a
behaviour of POE::Wheel::ReadWrite that is suprising, to say the least.  I
share it here because I suspect I'm not the only one this has bitten.

I had the following 2 lines
      $heap->{wheel}->flush();
      my $h = $self->{wheel}->get_output_handle;

The symptom was that the second of these two lines would sometimes throw a
"Can't call method on undefined value" error.  Which caused me to bang my
head on the desk for a while.

But then it dawned on me:
    - ->flush() pushes the data down to the OS layer;
    - POE is then getting a select() in somehow (haven't tracked this down);
    - the select shows the Wheel's write handle is ready;
    - the Wheel's write handler is invoked;
    - which invokes my "flushed" handler;
    - the flushed handler was deleting the wheel;
    - all the happens before ->flush returns;
    - by the time it returns, $self->{wheel} has been deleted.

The answer isn't don't use ->flush(), because ->put() can trigger a driver's
->flush(), or call it explicitly if you have autoflush on.

The solution is that all code that uses of ReadWrite need better detection of
"end of connection."

Now, is this "gotcha" documented anywhere?  Should it be?  Should there be a
module that turns ReadWrite's asynchronous behaviour into something easier to
deal with?

I suspect the answer to the last question is "yes, and you've just volunteered
to write it, dude."

-Philip




Reply via email to