Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: POE yield not working

by rcaputo (Chaplain)
on Feb 02, 2013 at 20:27 UTC ( [id://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.

Replies are listed 'Best First'.
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.

      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});

      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.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2024-04-25 23:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found