Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re: POE yield not working

by rcaputo (Chaplain)
on Feb 02, 2013 at 20:27 UTC ( #1016750=note: print w/ replies, xml ) Need Help??


in reply to POE yield not working

The reason the first call works is that you're passing parameters in your yield() call.

... $kernel->yield('keepalive', $io_wheel, $kernel); ....

The keepalive callback collects those parameters here:

... keepalive => sub { my ( $io_wheel, $kernel ) = @_[ ARG0, ARG1 ]; ....

The problem is that you're not continuing to pass those parameters in the delay. This might work better:

keepalive => sub { my ( $io_wheel, $kernel ) = @_[ ARG0, KERNEL ]; $io_wheel->put( "keepalive" ); $kernel->delay( 'keepalive' => 10, $io_wheel ); },

Notes:

  • You don't need to pass a POE::Kernel reference through, since that's given to you for free in every callback. I've removed it from delay(), and you should remove it from yield().
  • The rest of the code tracks wheels by their IDs. It might be more consistent and easier overall to pass the wheel ID instead of the reference. For example, if something destroys the object (deletes the wheel), the ID to object lookup will detect that it's gone away.


Comment on Re: POE yield not working
Select or Download Code
Re^2: POE yield not working
by SoulStyle (Initiate) on Feb 03, 2013 at 16:52 UTC
    Many thanks for this input, it is now working like intended. Since this little project is my first contact with POE please allow some more noobish questions:
    The rest of the code tracks wheels by their IDs. It might be more consistent and easier overall to pass the wheel ID instead of the reference. For example, if something destroys the object (deletes the wheel), the ID to object lookup will detect that it's gone away.
    Do you mean to rather use
    on_connect => sub { # Begin interacting with the server. my ( $kernel, $client_socket ) = @_[KERNEL, ARG0 ]; $_[HEAP]{client} = POE::Wheel::ReadWrite->new( Handle => $client_socket, InputEvent => "on_receive_data", ErrorEvent => "on_connect_error", ); $_[HEAP]{client}->put( "login monitor monitor", "log on", +); $kernel->yield( 'keepalive', $_[HEAP]{client} ); },
    instead of passing it to the variable $io_wheel?

    And in the same context, would you please be so kind as to elaborate following difference:

    $kernel->yield( 'keepalive', $_[HEAP]{client} );

    is used to address the ReadWrite instance.

    In the sub "on_connect_error" (see first post) following code is used to delete the wheel upon an error:

    delete $_[HEAP]{client}{$wheel_id};

    I don't understand the difference between these two. Still struggling with a lot aspects in POE and I appreciate each input.

      Regarding wheel ID vs. reference, I meant it might be better to pass around the client's wheel ID rather than a reference to the wheel itself. As in:

      $kernel->yield('keepalive', $io_wheel->ID, $kernel);
      and
      keepalive => sub { my ( $io_wheel_id, $kernel, $heap ) = @_[ ARG0, KERNEL ]; return unless exists $heap->{clients}{$io_wheel_id}; $heap->{clients}{$io_wheel_id}->put("keepalive"); $kernel->delay( 'keepalive' => 10, $io_wheel_id ); },

      It's more work, for you and for the program, but it stops repeating the timer after the client has disconnected. Of course, another way is to make sure that the timer is canceled wherever you are deleting the client. If you find yourself doing that in multiple places, refactor it into a subroutine like:

      sub delete_client { my ($kernel, $heap, $io_wheel_id) = @_; delete $heap->{clients}{$io_wheel_id}; $kernel->delay(keepalive => undef); }
      which would be called the usual Perlish way
      on_connect_error => sub { # Handle client error, including disconnect. my $wheel_id = $_[ARG3]; delete_client(@_[KERNEL, HEAP], $wheel_id); },
      It really helps when cleanup gets complex, as it often does when programs evolve and grow.

      And in the same context, would you please be so kind as to elaborate following difference:

      $kernel->yield( 'keepalive', $_[HEAP]{client} );
      is used to address the ReadWrite instance.

      In the sub "on_connect_error" (see first post) following code is used to delete the wheel upon an error:

      delete $_[HEAP]{client}{$wheel_id};
      I don't understand the difference between these two. Still struggling with a lot aspects in POE and I appreciate each input.

      I think the first one is a typo. It refers to the hash of all clients rather than a particular client. It should probably be

      $kernel->yield('keepalive', $_[HEAP]{client}{$wheel_id});

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1016750]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (11)
As of 2014-08-01 17:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Who would be the most fun to work for?















    Results (36 votes), past polls