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:

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.