Ace128 has asked for the wisdom of the Perl Monks concerning the following question:

Greetings Monks,

Well, I have this rather large application, and I just decided to "convert" a "standard" script into a more object oriented ala POE. (POE seems really handy, particularly in this case).
Anyway, broken down the important code related to the problem I have:
POE::Session->create ( inline_states => { _start => \&startApplication, searchmode => \&searchMode, } ); POE::Session->create ( inline_states => { _start => \&searchUpdate, } ); $poe_kernel->run(); # Relevant is also: sub startApplication { $poe_main_window->Toplevel(-title => "Search"); .... jadajadajada .... } sub searchUpdate { while(1) { next if (!$INTERESTING); ! DO ALOT ! } }
Now, I thought that these two sessions would start as a seperate "thread", but apparently not, since the first one is never shown (the first session is a Tk based GUI). Yes, apparently, there needs to be some $session->postback set else the session will end anyway... (compared to Mainloop) (Why? And how to fix this btw (If I dont wanna set any postbacks...)?)
If I remove the "second" session, the GUI is shown.

Ideas how to run these simultaneously (as this is what POE is supposed to be good at, eh)?

Thanks,
Ace

Replies are listed 'Best First'.
Re: POE, Tk, Simultaneous problem!
by thundergnat (Deacon) on Sep 28, 2005 at 17:11 UTC

    Part of your problem is that you are starting up two event loops which don't seem to be yielding control to each other. Using Tk under POE ia a different kettle of fish from using it directly. You need to constantly be aware what part of the event loop has control and to delegate control to the appropriate event handlers when necessary.

    Maybe this will help illustrate. Here's a contrived example. A text widget is constantly being filled with random numbers while being searched for strings of 12 odd digits in a row. When one is found, it pauses until you tell it to search again.

    use warnings; use strict; use Tk; use POE; POE::Session->create ( inline_states => { _start => \&startApplication, search_again => \&search_again, search => \&searchUpdate, } ); $poe_kernel->run(); exit 0; sub startApplication { my ( $kernel, $session, $heap ) = @_[ KERNEL, SESSION, HEAP ]; $poe_main_window->Label( -text => 'Search for at least 12 odd random digits in a row' )->pack; $heap->{text} = $poe_main_window->Text->pack(-expand => '1', -fill + => 'both'); $heap->{text}->tagConfigure('highlight', -background => 'orange'); $heap->{search_run} = 1; $heap->{search_index} = '1.0'; $poe_main_window->Button( -text => "Search Again", -command => $session->postback('search_again') )->pack; $kernel->yield('search'); } sub searchUpdate { if ($_[HEAP]->{search_run}){ my $count; my $search_index = $_[HEAP]->{text}->search( '-regexp', -count => \$count, '--', '[13579]{12,}', $_[HEAP]->{search_index}, $_[HEAP]->{search_index}.' lineend' ); if ($search_index){ $_[HEAP]->{text}->tagAdd('highlight', $search_index, $sear +ch_index." +$count".'c'); $_[HEAP]->{search_run} = 0; $_[HEAP]->{search_index} = $_[HEAP]->{text}->index($search +_index."+$count".'c'); } if ($_[HEAP]->{search_run}){ my $line; for (0..69){ $line .= int rand 10; } $_[HEAP]->{text}->insert('end',"$line\n"); if ($_[HEAP]->{text}->index('end') > 25){ $_[HEAP]->{text}->delete('1.0','1.0 lineend +1c'); $_[HEAP]->{search_index} = '1.0'; } } } $_[KERNEL]->yield('search'); } sub search_again { $_[HEAP]->{text}->tagRemove('highlight', '1.0', 'end'); $_[HEAP]->{search_run} = 1; $_[KERNEL]->yield('search'); }
      Wow! You ppl here really take this helping out seriously! :)

      Well, $INTERESTING was supposed to be controlled from Session1...
Re: POE, Tk, Simultaneous problem!
by GrandFather (Saint) on Sep 28, 2005 at 04:51 UTC

    Test case code (below) generates the errors shown. Looks like POE doesn't do Tk.

    * * POE can't use multiple event loops at once. * You used Select and Tk. * BEGIN failed--compilation aborted at C:/Perl/site/lib/POE/Kernel.pm li +ne 491. Compilation failed in require at (eval 14)[C:/Perl/site/lib/POE.pm:40] + line 1. BEGIN failed--compilation aborted at (eval 14)[C:/Perl/site/lib/POE.pm +:40] line 1. could not import qw(Kernel) at noname.pl line 4 BEGIN failed--compilation aborted at noname.pl line 4.

    Perl is Huffman encoded by design.
      Change that too:
      use warnings; use strict; use Tk; use POE; my $killAll = 0; POE::Session->create (inline_states => {_start => \&startApplication, searchmode => \&sea +rchMode}); POE::Session->create (inline_states => {_start => \&searchUpdate}); POE::Kernel->run(); # Relevant is also: sub startApplication { $poe_main_window->Toplevel(-title => "Search"); $killAll = 1; } sub searchUpdate { while (! $killAll) { sleep 1; print '.'; } }
      That is,
      use $poe_main_window (which is exported Tk Window by POE).
      remove the MainLoop (guess that its's not used with POE!)

        Actually you only need:

        use warnings; use strict; use Tk; use POE;

        to get the error! Something to do with how the Tk event loop gets replaced by the POE event loop. The documentation is not clear on this matter!

        I'm doing this on Windows with ActiveState Perl. There may be issues that a different if you are using a different platform or cygwin Perl.


        Perl is Huffman encoded by design.
Re: POE, Tk, Simultaneous problem!
by Anonymous Monk on Sep 28, 2005 at 07:01 UTC
      Yes, thank you. Seen that, but that doesnt really help me with my problem!
Re: POE, Tk, Simultaneous problem!
by zentara (Cardinal) on Sep 28, 2005 at 10:56 UTC
      Thanks, but seen that too.. no real help there either...
Re: POE, Tk, Simultaneous problem!
by Anonymous Monk on Sep 28, 2005 at 07:09 UTC
Re: POE, Tk, Simultaneous problem!
by rcaputo (Chaplain) on Sep 29, 2005 at 03:56 UTC

    POE uses event-based, cooperative multitasking. It's the same stuff Tk uses. Your ! DO A LOT ! will freeze the rest of the program.

    POE::Wheel::Run can spawn some code to run in another process. You may not need to use it, however.

    Your later example uses sleep(). POE and Tk have functions to execute callbacks after time has elapsed. If you're going to poll and sleep, maybe you can delay and callback instead. POE and Tk will process other events while you're waiting for your callback.

    Some other notes on looping and sleeping: http://poe.perl.org/?POE_Cookbook/Looping and http://poe.perl.org/?POE_Cookbook/Waiting