Re: Avoiding runtime Session collision

2005-05-02 Thread Lance_Braswell







Rodney Rindels [EMAIL PROTECTED] wrote on 05/02/2005 04:43:23 PM:

 I'm sure this is just my brain not properly doing a literal join. But
 I'm confused about how to properly ask the kernel what state a session
 is in,
 ie.

 Does a Session Exist?
 If so What state is the Session in?
 Avoiding shutdown until a Session is in state x or y ?
 Currently I am using sigtraps and handlers to shutdown the kernel, but
 It would be nice to extend that logic out if any of the Sessions I
 define are not in a waiting state, or don't have any wheels attached.


Handle all your signals and set a global $shutdown in the signal handlers.
Then have your sessions periodically check $shutdown and act appropriately.

  From what I've assembled thusfar, I'm guessing I'll have to alias all
 my sessions so I can know who to ask the kernel about.

 Basically every minute I have to fire an event that initiaties other
 sessions if those sessions are supposed to fire at that time of day. I'm
 assuming I'll have to keep some runtime information in a global about
 who fired and when as I don't see a shared kernel area for this type of
 data. In short I can never have two sessions of the same type running at
 the same time and have to avoid runtime collisions, as well as some of
 our customers only allow a single connection per day.

I'm not sure if I understand completely. But what is the session doing? I
guess you could:

my $session = $kernel-alias_resolve(mysession) || start_mysession; #
but...

I guess I'm wondering if you are having seperate sessions be psuedo events
when instead you might want to have a session that can accept postings from
your scheduler? In other words why the ambiguity about whether or not a
session is active? Need more info here.

 A design concern I have is whether I'm going to have to keep my sessions
 around long term because of tracking their own behaviors as opposed as
 to like a shared kernel $_[HEAP] that could do that for me somehow


I always think of any data structure outside of the event definitions (i.e.
globals) as being something like the heap of the kernel? I don't think
there is anything wrong with this if that's your concern.

 Last question about _start. I notice that when you define a session, its
 _start runs immediately, is there a way to initiate a Session at
 daemonize time and not actually have it fire until it _start gets
 explicitly called.


Have your session's _start call something like
$kernel-yield('daemon_init') and then define a daemon_init handler. I
think that will run the first chance it gets after the kernel has started.
Then put everything you want in that handler.

 Rod




Re: Fwd: Re: POE::Component::Client::DNS woes

2005-04-28 Thread Lance_Braswell




Untested: spawn several several PoCo::Client::DNS aliases. You could
either strictly round-robin your posting to the spawned resolvers in
start_next_lookup. Or, if you really want to balance things out, keep up
with how many queries each resolver is currently handling by incrementing
some counter at the start of start_next_lookup and decrementing it in
got_answer. Then choose a resolver accordingly (don't forget to randomly
pick from resolvers that are available).
-
Lance Braswell - + 1 469 357 6112


   
 Lari Huttunen   
 [EMAIL PROTECTED] 
 tu.netTo 
   poe@perl.org  
 04/28/2005 01:45   cc 
 PM
   Subject 
   Fwd: Re:
 Please respond to POE::Component::Client::DNS woes
 [EMAIL PROTECTED] 
  tu.net  
   
   
   
   




Oops, sorry forgot to CC: the list.

--  Original Message  --
Subject: Re: POE::Component::Client::DNS woes
To:  Mathieu Longtin [EMAIL PROTECTED]
From:Lari Huttunen [EMAIL PROTECTED]
Date:Thu, 28 Apr 2005 21:39:57 +0300


On 21:00:51 28/04/2005 Mathieu Longtin [EMAIL PROTECTED] wrote:
 Hum, if the first DNS servers works, why should it try the
 other ones?

To even out the query load between the different servers, but yes I see
your point. :) Which means that I will probably have implement some kind
of a round-robin logic for the queries, maybe? I would like to use the
exisiting modules but what I was looking for is distribution of the query
load between many different nameservers.

--
Sincerely,

Lari Huttunen





Re: Anybody did this?

2005-04-20 Thread Lance_Braswell




Also, be careful not to get the publish/subscribe thing confused with
something like a strategy. Your insert, log, and email steps are not likely
to be independent from each other. Publish/subscribe make me think in terms
of some independence between different subscribers.


Will Lowe [EMAIL PROTECTED] wrote on 04/20/2005 12:28:26 PM:

   In POE, is it possible to register multiple event handlers for a
single
  event? sort of like publish/subscribe messaging. For example, suppose I
have
  an order event, I'd like several handlers to be invoked: one to
insert
  into db, one to log, one to send email, etc. I could send multiple
events,
  but that's not as nice.

 Just have the one handler you register call the others?  Via
 $kernel-yield() or direct foo(); calls?

 --
 Will



Re: Syslog child on Windows

2005-03-31 Thread Lance_Braswell




Also, if you don't need for the DBI stuff to be threaded in with the rest
of your POE app, you can just initially create another Session that is a
Queue. Then write each $msg that comes in from PoCo::Server::Syslog to the
Queue. The Queue itself just sets an alarm to periodically process itself
in a POE::Wheel::Run or you can just fork it. The child part would then
handle the database connection and writing. I do this all the time and it
works really well.
-
Lance Braswell - + 1 469 357 6112


   
 David Davis   
 [EMAIL PROTECTED] 
 l.com To 
   Jim [EMAIL PROTECTED]   
 03/31/2005 11:17   cc 
 AMpoe@perl.org
   Subject 
   Re: Syslog child on Windows 
 Please respond to 
David Davis
 [EMAIL PROTECTED] 
  l.com   
   
   




There are quite a few DBI components for POE.  You could use one of
those.  I'm partial to mine, but you should judge for yourself.

http://cpan.teknikill.net/?poe*dbi

--
David Davis
Perl Programmer
http://teknikill.net/

$7.95 per month hosting
WITH ssh access
http://hosting.teknikill.net/

On Thu, 31 Mar 2005 11:41:28 -0500, Jim [EMAIL PROTECTED] wrote:
 I have a perl Syslog server setup on a windows box because it's connected
to
 a RAID Array.  I'm using POE as the Syslog server code and I'm storing
the
 syslog data into a DB2 database.  Here is what I currently have:

 use warnings;
 use strict;

 use POE;
 use POE::Component::Server::Syslog;
 use DBI; # library for performing database functions
 use DBD::DB2;
 use DBD::DB2::Constants;
 # use Mail::SendMail;

 POE::Component::Server::Syslog-spawn(
 BindAddress = '129.37.2.201',
 InputState = \client_input,
 ErrorState = \client_error,
 );

 my $debug = 1;

 $poe_kernel-run();

 ##

 sub client_input {

   # Get the syslog hash
   my $msg = $_[ARG0];
   my $databaseHandle;
   my $connectFailureFlag = 0;
   my $search;
   my $sth;
   my $dbName = vpn;
   # Parse the data for DB entry
   $msg-{'msg'} =~ /^(.*?) (\d+)\/(\d+)\/(\d+) (\d+):(\d+):(\d+)\.(\d+)
 SEV=. (.*?)$/;

   if ($debug) {
print Host: .$msg-{'host'}.\n;
print Severity: .$msg-{'severity'}.\n;
print  Msg: .$msg-{'msg'}.\n;
my $databaseHandle = DBI-connect(DBI:DB2:$dbName,x,xx)
or
 $connectFailureFlag = 1;
 if ($connectFailureFlag == 1){ warn Unable to establish with
 DB2:$dbName due to $DBI::errstr\n; }
 elsif ($connectFailureFlag == 0){ # connected to DB
  $search = INSERT INTO VPN.SYSLOG_C3K (DATE_TIME, DEVICE, SEV, MSG)
 values('$4-$2-$3-$5.$6.$7.$8', '.$msg-{'host'}.',
.$msg-{'severity'}.,
 '$9');
   $sth = $databaseHandle-prepare($search); # prepare the statement
to
 read from the DB
   $sth-execute(); # execute the query
 $sth-finish;
  $databaseHandle-disconnect or warn Disconnection failed:
 $DBI::errstr\n;
}
print $2.$3.$4.$5.$6.$7.$8 $1 $9\n\n;
   } # if ($debug)
 }

 sub client_error {
   # Something went wrong with the syslog message
   # Figure out what to do, if anything, in this case later
 warn BAD MESSAGE: $_[ARG0];
 }

 What I'd like to do is collect the syslog data into an array while having
 another process pull the data out of that array and put into the
database.
 That way, I'm not creating database connections everytime I get a syslog
 message.  Hopefully I'm clear in what I'm asking for. :-)






Re: Why can't I retrieve this POE session's options?

2005-03-30 Thread Lance_Braswell
I was trying to be cute by inserting a Python reference whenever possible 
and it masked the real change I made ;). Sorry about that. The real change 
was using an option key name of 'myname' as opposed to 'MyName'.

The hashref that is passed as the value of 'options' in 
POE::Session::create is imported as is, meaing you have a 
$self-[SE_OPTIONS]-{MyName} = 'Tim' in your session after create. 
However, every invocation of POE::Session::option _lower-cases_ the key 
name on both setting and getting. So your program initializes options with 
a 'MyName' but your subsequent:

my $name = $_[SESSION]-option( 'MyName' );

in handler1 is looking for a 'myname' (lower-cased) option internally 
which isn't defined yet hence the uninitialized value in concat. error . 
Doing this:

$_[SESSION]-option( 'MyName', 'Mud' );

sets a lower-case 'myname' option internally which is why it works for 
handler2.

But like you have figured out you probably are wanting something else 
instead.

It probably still needs to be fixed in POE::Session though.

-
Lance Braswell - + 1 469 357 6112 



Tim Klein [EMAIL PROTECTED] 
03/30/2005 06:44 PM

To
poe@perl.org
cc

Subject
Re: Why can't I retrieve this POE session's options?






You mean you can substitute 'Tim the Enchanter' for 'Tim' in my 
program, and it works for you?  It doesn't for me; I get the very 
same output as with 'Tim'.

Tim

I think it's a bug. In POE::Session options are stored like so:

$self-[SE_OPTIONS] = $params{+CREATE_OPTIONS}

However the processing in POE::Session::option is done with my $flag =
lc(shift) on both getting and setting.

Using 'myname' = 'Tim the Enchanter' works for instance.
-
Lance Braswell - + 1 469 357 6112

I expected the following short program to print My name is Tim
followed by My name is Mud.  Instead, this is the output:

My name is
Use of uninitialized value in concatenation (.) or string at opt.pl line
25.
My name is Mud

Apparently, the 'MyName' option isn't getting registered properly
during the creation of the session.  But when I later set the same
option using the option() command, it works fine.

Can someone spot what I'm doing wrong, most likely in my create()
call?  It's probably something stupid, but I just can't see it.
Thanks for any help!

Tim



#!/usr/bin/perl

use warnings;
use strict;
use POE;

POE::Session-create
   (
inline_states =
{
_start = \startup,
event1 = \handler1,
event2 = \handler2,
},
options = { 'MyName' = 'Tim' },
   );

POE::Kernel-run();


sub startup { $_[KERNEL]-yield('event1'); }

sub handler1 {
 my $name = $_[SESSION]-option( 'MyName' );
 print My name is $name\n;
 $_[KERNEL]-yield('event2');
}

sub handler2 {
 $_[SESSION]-option( 'MyName', 'Mud' );
 my $name = $_[SESSION]-option( 'MyName' );
 print My name is $name\n;
}




Re: Setting a variable in the heap

2004-09-09 Thread Lance_Braswell
It seems there is a handy Started argument to PoCo::Client::TCP::new. 
You can also do effectively the same thing by establishing a closure 
around $site below in one or more of your PoCo::Client::TCP event 
handlers.

The following is untested:

use POE qw(Component::Client::TCP);

foreach my $site ( qw/ site1 site2 site3 / ) {
POE::Component::Client::TCP-new
( RemoteAddress = $site,
  RemotePort = 6789,
  #Started = sub { $_[HEAP]-{sitename} = $site; }, # 
could do it with a closure
  Started = sub { $_[HEAP]-{sitename} = $_[ARG0]; }, # 
not a closure
  Args = [ $site ], 
  ServerInput = sub {
my ( $kernel, $heap, $input ) = @_[ KERNEL, HEAP, 
ARG0 ];
my $sitename = $heap-{sitename};
  # print got input from $site: $input\n; # a 
closure gets you the same thing
print got input from $sitename: $input\n;
  },
);
}
-
Lance Braswell - + 1 469 357 6112 



Jeff Konz [EMAIL PROTECTED] 
09/09/2004 09:17 PM
Please respond to
Jeff Konz [EMAIL PROTECTED]


To
[EMAIL PROTECTED]
cc

Subject
Setting a variable in the heap






Hello,

I am a new user of POE and I have a script that creates a connection
to a tcp server and am processing the data coming from that server.  I
have 7 different servers that I run the script against.

I would like to create a single POE script that does what I need.  I
know that I can set up individual sessions within the script to handle
this.  In order to process the data, my state needs to know what
system the data comes from.

The easiest way I see to do this is to have a variable in the sessions
heap that is something like:

heap-{sitename} = site1

So my question is two fold, first is this the proper syntax to do this
and second if it is, where do I put this statment within the POE
script( I.E. Within the new() construct of the
POE::Component::Client::TCP or somewhere else)?
 
I have read the docs that are available, but I can not find a
reference to setting vars within the heap.

Thanks for any help you can provide,

Jeff



using a separate session to process multiple client inputs from Component::Server::TCP

2004-03-24 Thread Lance_Braswell
First let me say that I think POE is awesome! It's been a mind-blowing 
couple of weeks trying to get my brain around it.

I am rewriting a Network Monitoring system where the clients periodically 
connect to my server and send things. Right now I am using a simple accept 
and forking IO::Socket::INET server. The problem is that we are at the 
mercy of the clients and sometimes the clients hang or take a long time 
while sending data. Add to this that many clients may end up connecting at 
nearly the same time and you have a recipe for out of memory/cannot fork 
conditions. Some of this is due to other design problems. But I am doing a 
complete rewrite of the whole thing so I will fix those as well. So on the 
server I know I want to do something more robust and POE seems to 
encapsulate that already so that's what I am going to use.

Basically my server would be getting an XML document from the client. I'll 
only process the data from the client after it disconnects. No need to 
answer back to it (at least not yet). I would also like to batch up the 
responses and process them with POE::Wheel::Run (because processing the 
queue involves a lot of slow running parsing of some XML and entering it 
into a database). So I am building up a queue and periodically processing 
it. The next step would be to take the entire queue, hand it of to 
POE::Wheel::Run, zero the queue, and keep moving. In my mind this is a Poe 
Man's pre-forking server. Here (below) is a skeleton of what I have so far 
to demonstrate this (but w/o the POE::Wheel::Run). Here are my questions:

1) Am I on the right track to have the Server and the queue processing in 
separate sessions where the Server posts to the queue's session?
2) Is there any way to high-water mark the queue so that it is processed 
immediately if reaching that mark? Or should I just be happy with 
periodically processing the queue as I have done below?
3) Am I using delay_set below in the way it was intended to be used?
4) Can anyone point me to examples of timing-out a client connection 
gracefully after a certain period of time.
5) Am I crazy?

Thanks for reading,
Lance

#!/usr/bin/perl

# after http://poe.perl.org/?POE_Cookbook/TCP_Servers

use warnings;
use strict;

use POE qw(Component::Server::TCP);

#sub MAX_QUEUE_SIZE { 3 }
sub QUEUE_FLUSH_TIME { 10 } # in seconds to wait before flushing the input 
queue

POE::Component::Server::TCP-new(
   Alias = server,
   Port = 11211,
   ClientInput = sub {
  my ( $session, $heap, $input ) = @_[ SESSION, HEAP, ARG0 ];
  print Session , $session-ID(),  got input: $input\n;
  $heap-{client_data} .= $input;
  $heap-{client}-put($input);
   },
   ClientDisconnected = sub {
  my ( $kernel, $session, $heap ) = @_[ KERNEL, SESSION, HEAP ];
  my $client_data = $heap-{client_data};
  if ( defined( $client_data ) ) {
 $kernel-post( queue_handler = add_client_data = 
$client_data );
  } else {
 print server didn't get back any client_data\n;
  }
   },
);

POE::Session-create(
   inline_states = {
  _start   = sub {
 my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
 $heap-{queue} = [];
 $kernel-alias_set(queue_handler);
 $kernel-delay_set(process_queue, QUEUE_FLUSH_TIME);
  },
  add_client_data = sub {
 my ( $kernel, $heap, $client_data ) = @_[ KERNEL, HEAP, ARG0 ];
 print queue_handler session got some client_data: 
$client_data\n;
 push( @{ $heap-{queue} }, $client_data );

 # I would like to process the queue immediately if it reaches 
MAX_QUEUE_SIZE
 # but the following doesn't work. I know why but I don't know how 
to fix it.
 # Maybe I should just depend on periodic processing of the queue 
instead since
 # it's being done anyway
 #if ( ( scalar( @{ $heap-{queue} } ) = MAX_QUEUE_SIZE )
 #   ! $heap-{process_queue_posted} ) {
 #  $kernel-yield(process_queue);
 #  $heap-{process_queue_posted} = 1;
 #}
  },
  process_queue = sub {
 my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
 print time to process queue\n;
 # This would eventually use a POE::Wheel::Run here to process the 
whole queue
 while( @{$heap-{queue}} ) {
my $client_data = shift( @{$heap-{queue}} );
print queue_handler session\'s process_queue event processed: 
$client_data\n;
 }
 # see comments above in add_client_data
 #$heap-{process_queue_posted} = 0;
 $kernel-delay_set(process_queue, QUEUE_FLUSH_TIME);
  }
   }
);

$poe_kernel-run();
exit 0;