EzDevInfo.com

poe

POE is a portable perl multitasking and networking framework for any event loop. POE: Perl Object Environment

How to properly shut down POE and POE::Session?

With POE calling POE::Kernel->stop() results in immediately shutdown. How does one request a graceful shutdown, waiting for the yield, post, call FIFO to be empty before shutting down?


Source: (StackOverflow)

Making an IRC bot - how can I let people !eval perl/javascript code?

I'm working on a bot in Perl (based on POE) and so far so good, but I can't figure out how can I add a !js or !perl command to evaluate respective code and return one line of output to be printed into the channel. I found App::EvalServer but I don't get how to use it.

Thanks for any help!


Source: (StackOverflow)

Advertisements

How does variable scoping work in a POE session?

Can anyone explain how variable scoping works within a POE session? What is the proper way to pass state within the session, without impacting other sessions?

Thanks Josh


Source: (StackOverflow)

Is there a Perl POE module for monitoring a database table for changes?

Is there any Wheel /POCO /Option to do this in Perl using the POE module: I want to monitor a DB table for changed records (deleting /insert/ update) and react accordingly to those changes.

If yes could one provide some code or a link that shows this?


Source: (StackOverflow)

Writing a modular aggregator and normalizer in Perl

I've just entered into an environment where I am much more free to choose whatever approach I want for a project (meaning full access to the CPAN and no module-approval-by-committee), but I'm a little out of touch with the new hotnesses, so I thought I'd solicit for ideas here.

My project involves scraping multiple sources with varying formats (html, zipped text, csv, etc.) normalizing and then processing them into some sort of datastore. The pulls need to happen at programmable intervals and I'd like to make the back-end modular so that similar sources can use the same codebase. It also needs to be able to respond via the web with a simple status of running processes (nothing fancy). I was thinking POE might be a good idea with several collector processes reporting to one master, but are there any specific modules in POE (or elsewhere) that anyone thinks I should have a look at?


Source: (StackOverflow)

Where can I read a clear explanation of POE (Perl Object Environment)?

I am searching for about a week for a good and clear tutorial for POE that is relevant to 2010 and didn't find one.

I found some tutorials in the Stack Overflow question Where can I find books or tutorials for Perl’s POE? under the poe tag but most of the materials are old and not clear.

Could someone provide a clear link/lecture/tutorials about POE if there are any? If not, it would be awesome if someone writes POE tutorials for beginners and advanced users; it could help the Perl community a lot.


Source: (StackOverflow)

How do I correctly shutdown a Bot::BasicBot bot (based on POE::Component::IRC)?

This is a sample script. When I hit Ctrl+C, the bot quits IRC but it reconnects back after some time. How do I shut down the bot correctly?

#!/usr/bin/perl

package main;

my $bot = Perlbot->new (server => 'irc.dal.net');

$SIG{'INT'} = 'Handler';
$SIG{'TERM'} = 'Handler';

sub Handler {
print "\nShutting down bot...\n";
$bot->shutdown('Killed.');
};

$bot->run;

package Perlbot;
use base qw(Bot::BasicBot);

sub connected {
my $self = shift;
$self->join('#codetestchan');
}

Source: (StackOverflow)

Perl POE - How to properly yielding a timer

I'm trying to get along with POE in perl. Very slowly I'm starting to grasp its concept but I'm far from really understanding it:

#!perl

use warnings;
use strict;

use IO::Socket;
use POE qw(Wheel::SocketFactory Wheel::ReadWrite);

my $SERVER_ADDR = '192.168.178.6';
my $SERVER_PORT = '50099';


POE::Session->create(
    inline_states => {
        _start => sub {
            # Start the server.
            $_[HEAP]{server} = POE::Wheel::SocketFactory->new(
                RemoteAddress  => $SERVER_ADDR,
                RemotePort     => $SERVER_PORT,
                SocketProtocol => 'udp',
                SuccessEvent   => "on_connect",
                FailureEvent   => "on_server_error",
            );
        },
        on_connect => sub {
            # Begin interacting with the server.
            my $client_socket = $_[ARG0];
            my $io_wheel      = POE::Wheel::ReadWrite->new(
                Handle     => $client_socket,
                InputEvent => "on_recieve_data",
                ErrorEvent => "on_connect_error",
            );
            $_[HEAP]{client}{ $io_wheel->ID() } = $io_wheel;

            $io_wheel->put( "login monitor monitor", "log on", );
        },

        on_server_error => sub {
            # Shut down server.
            my ( $operation, $errnum, $errstr ) = @_[ ARG0, ARG1, ARG2 ];
            warn "Server $operation error $errnum: $errstr\n";
            delete $_[HEAP]{server};
        },
        on_recieve_data => sub {
            # Handle client input.
            my ( $kernel, $input, $wheel_id ) = @_[ KERNEL, ARG0, ARG1 ];
            print "Received: $input\n";

            $kernel->yield('keepalive');
        },
        on_connect_error => sub {
            # Handle client error, including disconnect.
            my $wheel_id = $_[ARG3];
            delete $_[HEAP]{client}{$wheel_id};
        },
        keepalive => sub {
            my ( $kernel, $input, $wheel_id, $io_wheel ) = @_[ KERNEL, ARG0, ARG1, ARG2 ];
            $kernel->delay_add( keepalive => 10 );
            $io_wheel->put( "keepalive" );
        },
    }
);

POE::Kernel->run();
exit;

With this code I'm connecting to an UDP server application and read its status messages. Sofar it works with the exception of the

        keepalive => sub { ...

where I'm trying to add an timer that sends a keepalive package every 10 seconds.

How do I properly set such a timer and what is the best place to call it? I guess I'm messing up the back reference to the ReadWrite wheel but this connection between wheels/events etc is still something I'm struggling hard with. Any help and insight on this is greatly appreciated.


Source: (StackOverflow)

perl db poll results and poe wheel run

Im trying to write a app that polls a db table and processes the records found using Poe wheel run. This doesn't seems to work perfectly . Any suggestions out there.

The db poll sql

SELECT request_type destination port request FROM table1  
    WHERE STATUS_ID=200 limit 10;

results are printed to screen and picked up by poe wheel run

The poe wheel run

sub on_start {
        my $child = POE::Wheel::Run->new(
         Program => [ 'perl ~/sbin/db_poller.pl' ],
         StdoutEvent  => "got_child_stdout",
         StderrEvent  => "got_child_stderr",
         CloseEvent   => "got_child_close",
    );

The db poll produces results faster than the wheel can process.

Any design suggestions?


Source: (StackOverflow)

Is my POE::Component::IRC Event loop stuck?

I've been tasked with writing an IRC bot which will join channels on the internal IRC system here, and post messages to channels which don't appear to be used anymore, warning any potential users that the channel is about to be retired. Our IRC system has about 6,500 channels which need these messages posted to them, and the IRC server we use (a customised fork of Hybrid) limits concurrent channel joins to 100 per connection. In an attempt not to hit this limit, the code I've got is this :

if ($channel_list->{$channel}{joined}) {
    # If we're already joined, privmsg immediately
    $logger->info("Trying to message $channel");
    $data_entry->notified('true');
    $data_entry->update;
    $irc->yield(privmsg => $msg_channel, $message);
    $irc->yield(part => $msg_channel);
} else {
    # Otherwise join, and let the join event do the privmsg and part
    $logger->info("Trying to join $channel");
    $data_entry->notified('true');
    $data_entry->update;
    $irc->yield(join => $msg_channel);
}

i.e. it will see if we're joined already, and if we are, try to post the notification message, and then immediately part. If we're not joined, it tries to join first (and the join event will fire the message sending).

The problem is the code never seems to run the

$irc->yield(part => $msg_channel);

line, as eventually I start getting irc_405 events back from the IRC server saying the code has joined too many channels. Anyone got any idea what am I doing wrong?


Source: (StackOverflow)

How do I send a raw IRC message when using Bot::BasicBot

Bot::BasicBot provides a method for fetching the handle of the underlying POE::Component::IRC::State object, pocoirc(). Using this object handle, it seems like it should be possible to send a raw message like this:

sub said {
  my ($self, $message) = @_;
  $self->pocoirc()->yield('raw_events' => 1);
  $self->pocoirc()->yield('irc_raw_out' => 'RAW message');

However, this gives the error "Can't call method "yield" without a package or object reference" - the returned object doesn't seem to export the expected method. Have I misunderstood what kind of object I'm getting back, or how to trigger sending of a raw message?


Source: (StackOverflow)

How do I check if a user is authenticated with NickServ using POE::Component::IRC::State in Perl?

I'm trying to test whether a user is registered on FreeNode. nick_info() doesn't seem to return information about this, so I want to use $irc->yield(whois => $nick); and then grab the irc_whois event's reply. The problem is that I want to wait until this event is fired, so I created a global variable $whois_result and wrote a sub like this:

sub whois {
    my $nick = $_[0];
    $whois_result = 0;
    $irc->yield(whois => $nick);
    while($whois_result == 0) { }
    return $whois_result;
}

with the irc_whois handler looking like:

sub on_whois {
    $whois_result = $_[ARG0];
    print "DEBUG: irc_whois fired.\n";
}

Unfortunately, the event can't fire while the loop is running so this hangs. I'm sure there's a better way to do this, but I'm not familiar enough with this kind of programming to know. Any help would be greatly appreciated.


Source: (StackOverflow)

How do I get the responses from POE::Component::Client::HTTP?

My component

  POE::Component::Client::HTTP->spawn(
        Agent     => "MyScript/1.0",
        Alias     => 'browser',
        Timeout   => 60,
        FollowRedirects => 3,
  );

This is the event handler of another POE component from where the HTTP request is sent

 sub connected {
     my ($heap,$kernel) = @_[HEAP,KERNEL];
     my $request = POST 'http://mydomain.com', [qw(hello world this is my script)];
     $kernel->post('browser','request','response',$request);
   }

 sub response {
     print "I am inside the response handler!\n"; # It never reaches here
   }

I checked my Webserver logs and the HTTP request is sent correctly but it doesn't send the HTTP::Response object (or anything) to the response handler. What did I do wrong?


Source: (StackOverflow)

Understanding name spaces in POE-Tk

I posted "How to undersand the POE-Tk use of destroy?" in an attempt to reduce the bug in my production code to a test case. But it seems that the solution to the test case is not working in the full program.

The program is 800+ lines long so I am hesitant to post it in full. I realize that the snippets I provide here may be too short to be of any use, but I hope to get some direction in either where to look for a solution or what additional information I can provide.

Here is the Session::Create section of my POE-Tk app.


POE::Session->create(
    inline_states => {
    	_start		=> \&ui_start,
    	get_zone	=> \&get_zone,
    	ping		=> \&ping,
    	mk_disable	=> \&mk_disable,
    	mk_active	=> \&mk_active,
    	pop_up_add => \&pop_up_add,
    	add_button_press => sub {
    		my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
    		print "\nadd button pressed\n\n";
    		&validate;
    	},
    	ih_button_1_press => sub {
    		my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
    		print "\nih_button_1 pressed\n\n";
    		if( Tk::Exists($heap->{ih_mw}) ) {
    			print "\n\nih_mw exists in ih_button_1_press\n\n";
    		} else {
    			print "\n\nih_mw does not exist in ih_button_1_press\n\n";
    		}
    		1;
    		$heap->{ih_mw}->destroy if Tk::Exists($heap->{ih_mw});
    		&auth;
    	},
    	pop_up_del => \&pop_up_del,
    	auth		=> \&auth,
#   	validate	=> \&validate,
    	auth_routine => \&auth_routine,
    	raise_widget	=> \&raise_widget,
    	del_action	=> \&del_action,
    	over		=> sub { exit; }
    }
);

add_button_press is called here;


sub pop_up_add {
    ...
    my $add_but_2 = $add_frm_2->Button( 
    	-text => "Add Record",
    	-command => $session->postback("add_button_press"),
    	-font => "{Arial} 12 {bold}") -> pack(
    		-anchor => 'c',
    		-pady => 6,
    	);
    ...
}

validate creates the Toplevel widget $heap->{ih_mw};


sub validate {
    ...
    if( ! $valid ) {
    	print "\n! valid entered\n\n";
    	$heap->{label_text} .= "Add record anyway?";
    	my $lt_ref = \$heap->{label_text};
    ...
    	my $heap->{ih_mw} = $heap->{add_mw}->Toplevel( -title => "ih_mw");
    ...	
    	if( Tk::Exists($heap->{ih_mw}) ) {
    		print "\n\nih_mw exists in validate\n\n";
    	} else {
    		print "\n\nih_mw does not exist in validate\n\n";
    	}
    ...
    	my $ih_but1 = $heap->{ih_mw}->Button( -text => "Add",
    		-font => 'vfont',
    		-command => $session->postback("ih_button_1_press"),
    		)->pack( -pady => 5 );
    ...
}

Pressing $ih_but1 results in this;

C:\scripts\alias\resource>alias_poe_V-3_0_par.pl

add button pressed

sub validate called

! valid entered

ih_mw exists in validate

ih_button_1 pressed

ih_mw does not exist in ih_button_1_press

So the $heap->{ih_mw} widget seems to be unkown to the ih_button_1_press anonymous subroutine even with the inclusion of "($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];"


Source: (StackOverflow)

Perl POE::Wheel::FollowTail running in a thread not modifying global variables

In this program POE::Wheel::FollowTail works well for following the tail of a file, it is also running in a separate thread to simply monitor the progress of a compile job.
Inside the InputEvent handler there's a crude regex to extract compile results, and there everything is working fine, but I cannot get any result values to be accessible outside this sub. Even if I put result variables in the global scope they are not modified.

The program consists of one process running the compile job, another watching the log, and the main loop waiting.

Global scope:

my $Pass = 0;
my $Done = 0;

Then to kick off the monitoring:

threads->create(\&StartWatcher);

Where the watch-log file sub looks like this:

sub StartWatcher
{
my $logfile = "filename.log";

# Create the logfile watcher
POE::Session->create
    (
    inline_states => 
        {
        _start => sub 
            {
            $_[HEAP]{tailor} = POE::Wheel::FollowTail->new( Filename => $logfile, InputEvent => "got_log_line", );
            },
        got_log_line => sub 
            {
            $Pass += () = $_[ARG0] =~ /^\d+.*vcproj \- 0 error\(s\), \d+ warning\(s\)/g;
            $Done += () = $_[ARG0] =~ /^\d+.*vcproj \- \d+ error\(s\), \d+ warning\(s\)/g;
            print "POE InputEvent Pass: $Pass, Done: $Done\n"; # Debug output
            },
        }
    );

POE::Kernel->run();
}

The $logfile is being written by a Visual Studio compile job started using Win32::Process::Create and the main Perl execution is sitting in this loop waiting for the compiler to terminate, and producing a status output every second.

    while('true')
    {
    $ProcessObj->Wait(100);  # milliseconds wait
    $ProcessObj->GetExitCode($exitcode);
    if ( $exitcode == STILL_ACTIVE ) 
        {
        "Compiling... [$Done/$Count]  Pass: $Pass  Failed: $failed" 
            if($RunCounter++ % 10 == 0);
        next;
        }
    last;
    }

The output produced is similar to this:

POE InputEvent Pass: 1, Done: 1
Compiling... [0/91]  Pass: 0  Failed: 0                           

ie. in the InputEvent handler got_log_line the two global variables have been incremented, yet in the Perl main loop they are still at zero. I realise that I could do the print output from the InputEvent handler but why doesn't it modify global variables?

What is going wrong?


Source: (StackOverflow)