in reply to Confusion with POE & pTk

The problem is that your POE::Session instance is only doing one POEy thing: tailing that file. When it stops, POE recognizes that nothing POEy is happening and stops the seesion for inactivity.

The program needs a way to say: I'm getting events from Tk, so I'll stick around as long as the user interface is present.

POE has this, through POE::Session's postback() method. Postbacks are anonymous subroutines that, when called, post events. They also have a side effect: as long as they exist, the target session will remain alive.

Try this:

my $client_session = $_[KERNEL]->alias_resolve("myClient"); $top->Button( -text =>"Stop", -command => $client_session->postback("sendStop"), )->pack(-side=>'bottom');
When that button is pressed, Tk will send a "sendStop" to the "myClient" session. If it works, you can discard the stop() function.

The unresponsiveness happens because POE::Wheel::FollowTail has already read the entire file and generated events for each line. Your button press is enqueued at the end of all that.

You'll either have to wait it out, or not seek so far from the end of the file.

Replies are listed 'Best First'.
Re^2: Confusion with POE & pTk (not yet unconfused)
by cmv (Chaplain) on Oct 13, 2008 at 18:17 UTC
    Rocco-

    rcaputo++ for the response, and for all the work you've done on POE in general.

    To rephrase what you said (see if I understood correctly):

    The problem is that I only have one POE thing happening (the FollowTail), and when that session goes away, POE looks around and doesn't see anything else going on, so the whole POE kernel is exited. If I could find a way to keep the FollowTail session alive (even though it's not FollowTail-ing anymore) the kernel won't exit.

    To see if I understood this concept correctly, I simply added the following lines to the original script, right after the call to _processData():

    # This should simply create a dummy postback on the FollowTail session my $subref = $sess->postback('DontDie');

    This works fine, so I believe you are correct, but don't understand why the second POE::Session->create() in _displayData() isn't considered my second POEy thing? I assumed that this was my second session that it would force POE to hang around until the Tk stuff died (even after my FollowTail session exited).

    Obviously not, but I don't understand why...

    Finally, one side issue I encountered was that I wasn't able to use postback() to fire the sendStop event to the myClient session. As far as I could tell (in my environment) the command  $session->postback("sendStop") does nothing.

    Any help with these issues would be great!

    Thanks

    -Craig

      That's a good analysis, Craig.

      The second session, "Display" if I'm not lost, doesn't have any POEy things going on. The only reason it sticks around at all is because its alias implies that another session might send it events.

      Likewise, you might think the "myClient" alias should keep the FollowTail session alive even when there's nothing POEy going on in that session.

      In most cases that's true, but there's an exception: POE sessions will be terminated if every active session is waiting for an event from some other session. In POE terms, when all remaining sessions are kept alive only by an alias, then none of them will wake up to send an event. POE::Kernel recognizes this deadlock and signals the remaining sessions that they're idle. It literally sends a fake SIGIDLE signal to every session.

      If no session wakes up after SIGIDLE is broadcast, then POE::Kernel broadcasts one more fake signal, SIGZOMBIE. This kills off the sessions, and POE::Kernel->run() exits normally.

      If you export POE_TRACE_EVENTS=1 or export POE_TRACE_SIGNALS=1, you should see this happen.