POE::Component::Client::TCP recklessly removing aliases?

2003-11-06 Thread Nick Williams
POE::Component::Client::TCP can take an Alias parameter and it will set 
this alias onto the session on startup of the Session. It does not set 
the alias on reconnect. However, whenever the shutdown state is entered 
(e.g. connection dies), it removes the alias. Which means you have to 
manually manage the alias yourself. If you just use one of the quoted 
examples and schedule a reconnect event, you'll end up later on with a 
connected socket but without the alias. Either this makes the Alias 
parameter pointless, or I'm missing something.

Anyone care to enlighten me?

Nick



Re: POE::Session-call()

2004-02-11 Thread Nick Williams
Scott wrote:

[...]
If you're really only storing data, you really should use an object OR 
package in the ways I mentioned above.  Atleast, if you have any 
desire to maintain efficiency.

Now here I must note, that I didn't come up with the idea of removing 
inter-session calling all together.  I found the idea on the wiki.  
Now I'm not gonna name names, and I'm not gonna drag others in, 
because I am a proponent of the idea.  I think inter-session calling 
breaks POE Design patterns.  Forcing inter-session communication to be 
done via post()ing helps force people using the POE Framework to let 
POE do its thing, and stops people from doing things like creating 
sessions just for the sake of creating sessions.


I also have a need for inter-session calling, so I want to add my 
tuppence into this :-). Hopefully, my description below isn't so 
abstract to be non-sensical, but will convey why I need it.

I have a fairly complex system that runs various background monitoring 
tasks (using Wheel::Run) and also takes in requests from the network. 
Each new network request gains its own session for it to process all 
work. This work may take some time, also creating new Wheel::Runs, etc. 
The effect of some of the requests needs to change the frequency of the 
background monitoring that's going on, or needs to change some of the 
'global' data that dictates the manner in which the background 
processing is run. There is no synchronisation/locking of global data, 
so the only way to do that is to ask the session owner to make the 
change. When that type of event happens, we need to get a cross-session 
event to take place. We can't use post() all the time, because sometimes 
we need to ensure that the change happens before anything else in the 
queue is fired off, else we get out-of-order processing. It's a rare 
thing (only need this twice, in a codebase of ~20k lines of perl), but 
it does happen. I cannot see (within the constraints of our 
architecture) how I can achieve this without inter-session call 
functionality.

Nick.



Re: POE::Session-call()

2004-02-11 Thread Nick Williams
Scott wrote:

Nick Williams wrote:

Scott wrote:

[...]
If you're really only storing data, you really should use an object 
OR package in the ways I mentioned above.  Atleast, if you have any 
desire to maintain efficiency.

Now here I must note, that I didn't come up with the idea of 
removing inter-session calling all together.  I found the idea on 
the wiki.  Now I'm not gonna name names, and I'm not gonna drag 
others in, because I am a proponent of the idea.  I think 
inter-session calling breaks POE Design patterns.  Forcing 
inter-session communication to be done via post()ing helps force 
people using the POE Framework to let POE do its thing, and stops 
people from doing things like creating sessions just for the sake of 
creating sessions.




I also have a need for inter-session calling, so I want to add my 
tuppence into this :-). Hopefully, my description below isn't so 
abstract to be non-sensical, but will convey why I need it.

I have a fairly complex system that runs various background 
monitoring tasks (using Wheel::Run) and also takes in requests from 
the network. Each new network request gains its own session for it to 
process all work. This work may take some time, also creating new 
Wheel::Runs, etc. The effect of some of the requests needs to change 
the frequency of the background monitoring that's going on, or needs 
to change some of the 'global' data that dictates the manner in which 
the background processing is run. There is no synchronisation/locking 
of global data, so the only way to do that is to ask the session 
owner to make the change. When that type of event happens, we need to 
get a cross-session event to take place. We can't use post() all the 
time, because sometimes we need to ensure that the change happens 
before anything else in the queue is fired off, else we get 
out-of-order processing. It's a rare thing (only need this twice, in 
a codebase of ~20k lines of perl), but it does happen. I cannot see 
(within the constraints of our architecture) how I can achieve this 
without inter-session call functionality.

Nick.

But communication with child processes will never be synchronous, you 
have too many steps to go through to communicate with child processes 
(via pipes, or other methods, nothings going to be _RIGHT_NOW_)

I suppose the link I seem to be missing is why a subroutine call would 
not be satisfactory for this.
a subroutine call would be in the context of the currently active 
session, which is a session just there to deal with the current network 
request and should go away after that. Therefore I don't want to call 
the 'create-new-probe-which-will-fire-every-60secs' subroutine, because 
anything it creates would become a child of this current session and any 
alarms/delays it wants to set, and any events it wants to post to it's 
parent would go to me (this session) and not to the parent session which 
is looking after all background monitoring tasks.

[...]

but then again

I'm not even sure I really understand what you're saying.

It's hard to describe the system we've built in a small email, so I'm 
sorry for the confusion. My point is that in the possibly bizarre 
architecture we've built, we have a need for cross-session calls. 
Potentially, I could re-architect things to avoid that, however I'm not 
sure how at the moment (due to lack of locking in the global data) 
without very severe changes. Purity of design is great, but if it means 
I have to spend a week re-architecting compared to the current simple 
architecture can you see where I'm coming from? Pragmatism won in 
our system (funny that - same reason we're using perl and POE to start 
with...).

- Scott
Nick



Re: Proposal: Registered PIDs

2004-02-14 Thread Nick . Williams

Taking Chris' question further... why not implement wait queues (I'm
thinking along the lines of NT). Any session could declare it's interest
on a waitable object... and anyone with a reference to that object could
call wakeup on it. SIGCHLD handling is therefore just a special
case of this - you have a handle on the process, register you want to wait
on it. When the pid dies, the object referring to that PID could get a
wakeup event. If the waitqueue is empty, the process vaporises in a puff
of logic. Else the sessions that declared interest get woken.

Nick.

On Fri, 13 Feb 2004, Chris Fedde wrote:

 On Fri, 13 Feb 2004 23:31:56 -0500  Rocco Caputo wrote:
  +--
  | Proposal: Registered PIDs.
  |
  | Currently SIGCHLD is broadcast to every session that registers a CHLD
  | signal handler.  Quite often, this means every session with child
  | processes receives signals for every other one.  They all must track
  | their children and filter the incoming signals against theirs.
  |
  | A conversation in IRC reminded me about this issue.  I suggested the
  | customary pattern for dealing with broadcast SIGCHLD.
  |
  |   One of the parameters is the child PID.  You can return unless
  |   exists $heap-{mine}{$pid}
  |
  | Philip Gwyn and I had just covered the heavyhanded _signal event,
  | which is in the throes of deprecation.  It further occurred to me that
  | dispatching SIGCHLD to every session with a handler is often useless,
  | since most of them don't care one whit about any other session's
  | process IDs.
  |
  |   Maybe an optimization would be a Kernel registry mapping child PIDs
  |   to sessions.  After you fork, you can call $kernel-forked($pid) to
  |   focus that PIDs SIGCHLD on the current session.  POE::Wheel::Run
  |   could do it internally.
  |
  |   Unregistered PIDs would still be broadcast around.  And to be fair,
  |   I guess multiple sessions could register interest in a child PID.
  |   For whatever that's worth.
  |
  | This would require a new POE::Kernel method.  I wish it could be
  | incorporated into something like sig(CHLD = event), but re-
  | registering the SIGCHLD handler shouldn't be necessary for every new
  | process.
  +--

 Is SIGCHLD the only case where additonal context can be used by the
 Kernel to decide how to dispatch multicast events to sessions?  Is
 there a way to implement this feature so that other signals could
 take advantage of pushing selection behavior into kernel?

 --



Re: Shutting down kernel

2004-02-17 Thread Nick Williams
Rocco Caputo wrote:

On Mon, Feb 16, 2004 at 04:58:42PM -0600, Luke A. Kanies wrote:
 

Is
there a stop analog to $poe_kernel-run()?
   

Yes.  An experimental stop() was introduced in version 0.28.

 

Most cool! I didn't know about this until now - I've just switched over 
to using it and it works a charm.

Nick.


Re: PoCo::IRC, nicks in use, and sessions

2004-04-18 Thread Nick . Williams

In your code snippet, despite what you print out, you're not actually
changing $heap-{nick}, so you're reconnecting with the same name as
before...

Nick.

On Sun, 18 Apr 2004, Ciro wrote:

 Psilon, my modular POE IRC bot, is coming along fairly well. I've run
 into a bit of a snafu though. If the preset nick is in use, the bot will
 just hang there in a sort of half-connected state, until the connection
 times out, and the server gives a 443 Numeric. Theory on this below.

 I'd originally tried to deal with this situation by changing the nick,
 then issuing a ghost command to the local nickserv equivalent, but it
 never triggered the nick change so nothing else happend. Now I am just
 trying to reconnect with a random number (1-) appended to the nick,
 a-la AOL. (Code Below)

 This event is linked to 'on_irc_443', and it's part of it's own module,
 which includes wrappers for most of the PoCo::IRC commands (thus the
 $self references in the function calls. The names should be obvious.)

 I suppose this might be more of a question for IRC hackers than POE
 hackers, but I figure there has to be SOME crossover because the module
 exists. :) The crux of the problem seems to be that the IRC server only
 returns a Numeric Reply if the nick change FAILS (according to RFC 1459).
 Anyone have any idea how I might work around this so I don't have to drop
 and re-establish connection? If I can get that working, then I can get the
 nickserv's 'ghost' command implimented.

 Thanks!

 -Ciro



 #- Begin Code Snippet ---

 sub irc_433  #nickname in use
 {
 #use the serverhost as a session alias. Makes multi-net usage a lot easer
 #to debug
 my $self=shift;
 my $server=shift;
 my $sess=$self-{KERNEL}-alias_resolve($server);
 my $heap=$sess-get_heap(); #pull the heap with our settings
 my $nick=$heap-{nick};

 #drop existing connection
 $self-disconnect($server, : $nick in use.\n);

 #generate random nick
 $nick = $nick . int(rand(1)));

 print Reconnecting with nick: $nick\n;   #reconnect
 $self-{KERNEL}-post(
 $server,
 'connect',{
   Nick = $heap-{nick},
   Server   = $server,
   Username = $heap-{username},
   Ircname  = $heap-{realname},}
 );

 }







Re: New PoCo Guidelines

2004-08-13 Thread Nick Williams
Chris Fedde wrote:
On Tue, 10 Aug 2004 07:59:03 -0600  Wiggins d Anconia wrote:
 +--
 | I'll add another. I think at the very least POE (with the 'E') 
needs to
 | stay intact. I know the chatting convention has been to use 'PoCo',
 | but to keep the two related I think the full 'POE' spelling needs 
to be
 | included. The 'x' form definitely aligns well with the DBI - DBIx
 | pre-existing example.
 +--

Perhaps I'm too sentimental but I prefer names that are pronounceable.
PoCo has a high pronounce-ability.  As does POE::Co.  POEx seems to be 
just
a capitulation to some week previous art.  

Non-pronounceable? Bah!
/njw POEx chris in eye with stick. A pox on you!, he cries.
Okay, never mind me. Back to humming quietly to myself in the corner
Nick.
The most useful of the
DBI extensions are not even in the DBIx space.  Class::DBI for example.
We have an opportunity to avoid doing something that is just mundane.
Lets not miss it only to adhere to some perceived convention.
--
Chris Fedde



Re: POE::Wheel::Run on Win32, patch attached

2005-04-11 Thread Nick . Williams
On Mon, 11 Apr 2005, Bas Schulte wrote:


 On maandag, apr 11, 2005, at 16:03 Europe/Amsterdam, Merijn Broeren
 wrote:

  My collegue Nick Williams and I had a stab at making POE::Wheel::Run
  work on Win32.

 Isn't that like trying to sail the ocean in a bathtub?


Yes, but it's so nice to be able to pick up code that was written on unix
and for it to 'just work' on NT as well. Which we've got now. Extending
your analogy, POE is the GPS system that allows you to know where you're
going whether you're sailing a bathtub or a rickety old ship**.

Nick.

** analogies comparing ships to versions of *NIX could abound, but I'll
stop there. Suffice it to say that I'm using a very nice apple-branded
yacht.


Re: POE::Wheel::Run on Win32, patch attached

2005-04-13 Thread Nick Williams
Arthur Bergman wrote:
On 13 Apr 2005, at 11:49, Merijn Broeren wrote:

 kill 9,$$; :-)

 Did you fix that then? The perlfork manpage makes it sound like there
 will be leaks all over the place.


Hmmm.. to be honest I haven't actually touched the win32 code at all...
What is the specific reason we need to fork() for Wheel::Run?
Because code written using current Wheel::Run assumes parallelism.  Do 
you mean 'why aren't we using CreateProcess'? Because it seemed 
simpler/less-maintenance to keep the code base as similar as possible 
between the two different architectures. And you need to do most of the 
strange shenanigans with StdHandles even when using CreateProcess since 
the modules that exist for win32 don't expose the underlying win32 
facility of defining which handles to use in the spawned process.

Nick
Cheers
-
CTO @ Fotango Ltd
+447834716919
http://www.fotango.com/
-
CTO @ Fotango Ltd
+447834716919
http://www.fotango.com/
__
This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email
__



Bug in component Client::TCP...

2005-04-25 Thread Nick Williams
A strange one, so I'd like to solicit some opinions :-).
Client::TCP starts up with a 'server' wheel stashed away in the heap as 
a POE::Wheel::SocketFactory while it's waiting for the connection to 
occur. Once the connection is successful, it changes it's {server} in 
the heap to be a POE::Wheel::ReadWrite. This is commented as 'Ok to 
overwrite like this as of 0.13'.

The issue is that these two wheels have very different methods. The 
documentation says that if you want to send data, you should invoke 
$heap-{server}-put().  Which works just fine when {server} is the 
readwrite wheel. However, 'put' is not a method understood by a 
socketfactory.

Why might you be trying to send data when not connected? Well, the issue 
is that the connection might die/be reset by the app in which case the 
state engine will probably transition to 'reconnect' which will switch 
the {server} back into a SocketFactory. There might still be events 
waiting to fire (e.g. delays) which will with a bit of bad luck end up 
firing while {server} is a SocketFactory and not the ReadWrite wheel.

Now, I could change my code to check the isa() of the server wheel in 
all the callbacks, but it seems like a bit of a hack that I have to code 
defensively around the wheel changing underneath me.

Is there a better way of doing this?


Re: Client::TCP question

2005-10-17 Thread Nick Williams
The normal disconnection happens if the server closes the socket without 
error. So, your server is immediately closing the socket after sending 
the reply. This means that if you treat that as a failure and try to do 
the same thing again, you'll get exactly the same behaviour each time. 
You need to check the protocol for the server. It may not allow for a 
single session with many requests.


Nick.

wonton wrote:


Hello list,
I seem to be having a slight issue with a Client::TCP component and
would appreciate any guidance from those more experienced in the whys
and hows of POE.
In essence I have a very simple app. that connects to another server,
send an initialisation packet and then sends a request. If the
initialisation is successful, the same packet is echoed back to my app.
and then I attempt to send the request. However,  after the init.
packet is sent (and the response received) I receive this error Client
2 got read error 0 (Normal disconnection).

From a bit of googling I have determined that this is not an error as

such (informational). Now if I handle the server_error state explicitly
with a reconnect, the app loops indefinitely, initialising and then
the socket error and then reconnecting and then intialising again etc.
Obviously this isn't quite what I had in mind. (Ultimately there will
be many more of these messages travelling between my client and the
server and they are alway a request/response type setup).
Admittedly, I am only a couple of days in to POE and am still coming to
terms with the change in perspective required by POE, which begs the
question: am I approaching this incorrectly? trying to squeeze a square
block into a round hole? ;) or have i just missed something incredibly
simple?
any help/insight would be greatly appreciated.
cameron

 





memory (session) leaks in perl

2006-08-02 Thread Nick Williams
So, I've found the reason that recent releases of POE cause me to get 
memory leaks - I know others have had problems also, so I wanted to get 
an open discussion of what I'm being bitten by and possible ways to 
workaround this.


It turns out for me that my sessions aren't being garbage collected. In 
general, my POE system doesn't *require* the _stop event to be processed 
and so I never noticed this. However, peeking into the system shows a 
large number of sessions and I can see that none of the _stop events 
have been called.


This is because of the change:

 2005-11-07 06:59:07 (r1852) by hachi
 poe/lib/POE/Resource/Signals.pm M; poe/lib/POE/Resource/Sessions.pm M

   Change signal watchers so they keep sessions alive.
  
   WARNING: This is a major semantics change in POE. It has the

   potential to make code 'hang' in places where it formerly did not.
  
   This change is necessary so sessions expressing an interest in SIG

   CH?LD do not die prematurely. (There is a planned mandatory warning
   for reaped children that were not being watched.) This change fixes
   RT 15215.



The problem with this change is that if I set up a signal handler for 
something innocuous (e.g. to handle DIE, or one of my hand-rolled 
signals), this means that the session will do everything appropriately 
except be garbage collected. I think the intention of this change is 
reasonable, but to make it the default behavior for all possible signals 
is a bit keen. If I put in place a handler for a signal, it does NOT 
mean that I want to WAIT for the signal, it usually means that the 
signal shouldn't even happen, but that I'm putting in place a handler 
*in-case* it happens. It certainly shouldn't make my session persistent!


I'm not sure of the best way of fixing this. Possibly enhancing the 
API to have an explicity waitforsig() and maybesig()? (That's half 
tongue-in-cheek, but is actually one of the better solutions). In terms 
of normal API, a sig handler shouldn't block, so I would expect the 
sig() behaviour to follow that paradigm...


Thoughts, anyone?

Nick



Re: memory (session) leaks in perl

2006-08-03 Thread Nick . Williams
On Wed, 2 Aug 2006, Mathieu Longtin wrote:

 It was my understanding that a session would stay alive as
 long as it has child sessions. Did that behavior change?

No, this is not down to a child session - AFAIK, the behaviour there has
not changed.


 I'm in agreement with Nick here. If a session is stritly
 waiting for a child session to finish, then have it call
 waitpid.

 $_[KERNEL]-wait_for_child($session, state, @args);

 wait_for_child would add a link back to the current
 session, the same way set_delay does.

The issue is not wait_for_child, it's wait_for_signal (which doesn't
exist). The original problem report was that people were confused by
setting up a signal handler for UIDESTROY didn't make the session
persistent. That is standard signal semantics and the persistence
could've easily been changed by using aliases.

The new behaviour in POE (as of .3202) is that when placing a signal
handler on a session, e.g.
$kernel-sig('uidestroy', 'do_something');
that will now increment the reference count of the session and therefore
make that session persistent until the signal handler is deleted via
something (and note, not within the _stop event, since we don't get that
far).

Nick.


 -Mathieu


 --- Nick Williams [EMAIL PROTECTED] wrote:

  So, I've found the reason that recent releases of POE
  cause me to get
  memory leaks - I know others have had problems also, so I
  wanted to get
  an open discussion of what I'm being bitten by and
  possible ways to
  workaround this.
 
  It turns out for me that my sessions aren't being garbage
  collected. In
  general, my POE system doesn't *require* the _stop event
  to be processed
  and so I never noticed this. However, peeking into the
  system shows a
  large number of sessions and I can see that none of the
  _stop events
  have been called.
 
  This is because of the change:
 
2005-11-07 06:59:07 (r1852) by hachi
poe/lib/POE/Resource/Signals.pm M;
  poe/lib/POE/Resource/Sessions.pm M
 
  Change signal watchers so they keep sessions
  alive.
 
  WARNING: This is a major semantics change in POE.
  It has the
  potential to make code 'hang' in places where it
  formerly did not.
 
  This change is necessary so sessions expressing
  an interest in SIG
  CH?LD do not die prematurely. (There is a planned
  mandatory warning
  for reaped children that were not being watched.)
  This change fixes
  RT 15215.
 
 
 
  The problem with this change is that if I set up a signal
  handler for
  something innocuous (e.g. to handle DIE, or one of my
  hand-rolled
  signals), this means that the session will do everything
  appropriately
  except be garbage collected. I think the intention of
  this change is
  reasonable, but to make it the default behavior for all
  possible signals
  is a bit keen. If I put in place a handler for a signal,
  it does NOT
  mean that I want to WAIT for the signal, it usually means
  that the
  signal shouldn't even happen, but that I'm putting in
  place a handler
  *in-case* it happens. It certainly shouldn't make my
  session persistent!
 
  I'm not sure of the best way of fixing this. Possibly
  enhancing the
  API to have an explicity waitforsig() and maybesig()?
  (That's half
  tongue-in-cheek, but is actually one of the better
  solutions). In terms
  of normal API, a sig handler shouldn't block, so I
  would expect the
  sig() behaviour to follow that paradigm...
 
  Thoughts, anyone?
 
  Nick
 
 


 __
 Do You Yahoo!?
 Tired of spam?  Yahoo! Mail has the best spam protection around
 http://mail.yahoo.com



Re: memory (session) leaks in perl

2006-08-21 Thread Nick Williams
There appears to be a lack of opinion on this issue. Would it be 
therefore reasonable to backout the signal change in POE? Or can anyone 
suggest a way around the problem?


Nick.

[EMAIL PROTECTED] wrote:


On Wed, 2 Aug 2006, Mathieu Longtin wrote:

 


It was my understanding that a session would stay alive as
long as it has child sessions. Did that behavior change?
   



No, this is not down to a child session - AFAIK, the behaviour there has
not changed.

 


I'm in agreement with Nick here. If a session is stritly
waiting for a child session to finish, then have it call
waitpid.

$_[KERNEL]-wait_for_child($session, state, @args);

wait_for_child would add a link back to the current
session, the same way set_delay does.
   



The issue is not wait_for_child, it's wait_for_signal (which doesn't
exist). The original problem report was that people were confused by
setting up a signal handler for UIDESTROY didn't make the session
persistent. That is standard signal semantics and the persistence
could've easily been changed by using aliases.

The new behaviour in POE (as of .3202) is that when placing a signal
handler on a session, e.g.
$kernel-sig('uidestroy', 'do_something');
that will now increment the reference count of the session and therefore
make that session persistent until the signal handler is deleted via
something (and note, not within the _stop event, since we don't get that
far).

Nick.

 


-Mathieu


--- Nick Williams [EMAIL PROTECTED] wrote:

   


So, I've found the reason that recent releases of POE
cause me to get
memory leaks - I know others have had problems also, so I
wanted to get
an open discussion of what I'm being bitten by and
possible ways to
workaround this.

It turns out for me that my sessions aren't being garbage
collected. In
general, my POE system doesn't *require* the _stop event
to be processed
and so I never noticed this. However, peeking into the
system shows a
large number of sessions and I can see that none of the
_stop events
have been called.

This is because of the change:

 2005-11-07 06:59:07 (r1852) by hachi
 poe/lib/POE/Resource/Signals.pm M;
poe/lib/POE/Resource/Sessions.pm M

   Change signal watchers so they keep sessions
alive.

   WARNING: This is a major semantics change in POE.
It has the
   potential to make code 'hang' in places where it
formerly did not.

   This change is necessary so sessions expressing
an interest in SIG
   CH?LD do not die prematurely. (There is a planned
mandatory warning
   for reaped children that were not being watched.)
This change fixes
   RT 15215.



The problem with this change is that if I set up a signal
handler for
something innocuous (e.g. to handle DIE, or one of my
hand-rolled
signals), this means that the session will do everything
appropriately
except be garbage collected. I think the intention of
this change is
reasonable, but to make it the default behavior for all
possible signals
is a bit keen. If I put in place a handler for a signal,
it does NOT
mean that I want to WAIT for the signal, it usually means
that the
signal shouldn't even happen, but that I'm putting in
place a handler
*in-case* it happens. It certainly shouldn't make my
session persistent!

I'm not sure of the best way of fixing this. Possibly
enhancing the
API to have an explicity waitforsig() and maybesig()?
(That's half
tongue-in-cheek, but is actually one of the better
solutions). In terms
of normal API, a sig handler shouldn't block, so I
would expect the
sig() behaviour to follow that paradigm...

Thoughts, anyone?

Nick


 


__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

   





Re: memory (session) leaks in perl

2006-08-22 Thread Nick Williams

Rocco Caputo wrote:

Do you have a use case where it's impossible to do something under  
the new behavior?  I'm working under the assumption that a session  
can always find a way to call sig(YOUR_SIGNAL_HERE = undef) when  
it's ready to be destroyed.




When it's ready to be destroyed is the key. The new behaviour means 
that sessions need to track that themselves and (in effect) manage their 
own reference counting independent of POE's. Before, they could just 
rely on POE to let them know via _stop. Now, _stop is no longer called 
unless the session clears the sig first. This is just a catch-22. And it 
leaves a race condition whereby the session exists but has declared it 
no longer wants the signal.


To be fair regarding discussions on this list, Jonathan Steinert  
announced the intent to make sig() hold sessions alive in his 19  
October 2005 message titled Nastiness, and wrapping up signal  
reforms.  I replied that day with:


Big change.  I don't mind this; the old semantics of not holding a  
reference count were tied to _signal, which delivered signals  
without sessions explicitly asking for them.  _signal is gone now,  
so we can tie the explicit interest of sig() into a reference count  
to keep the session alive.



Nobody else responded.  17 days later I replied with a public go- 
ahead to make the change.




Yes, I realise that there was this discussion previously. However, 
speaking purely for myself, I didn't understand the impact of this at 
the time, since I wasn't cognizant of the internals of session reference 
counting at the time. Now I've looked at this, and I can't see how the 
new implementation makes sense.


My issue is that that the bugzilla that Jonathan was attempting to fix 
is just trivial to fix using existing POE mechanisms of aliases, since 
there's an easy point at which you know you want to start the 
persistence of the session, and there's a well-defined point at which 
you can release the persistence. However, by making the behaviour of 
persistence implicit within signals, there is simply no way to achieve 
the opposite effect (automatic garbage collection). The user (the 
application) must decide at which point it has no more work to do and at 
that point it can then clear the signal. And only then will POE do it's 
garbage collection and call back to the application. This just doesn't 
make sense. Especially when you compare signals in POE with signals in 
other dispatchers. Having a handler configured for a signal should not 
make that process persistent.


Maybe I'm thinking about it wrong. To me, explicit interest of sig() 
does not mean to me that I (this session) want to stay around until that 
sig, it means to me that it's merely putting in place a handler IN CASE 
of that sig. It's a really really important distinction. With the huge 
differentiator that the latter behaviour of 'in-case-of-handlers' CANNOT 
be achieved in the new POE signal world without careful application 
coding and ignoring any of the benefits of POE's internal garbage 
collection.


As a compromise, I've also proposed implicitly that maybe we should have 
a new function wait_for_sig() as well as just sig(), so that we can make 
the difference in semantics explicit to users. I don't mind which way 
around the functions and semantics are achieved, so long as there is a 
way of doing this.


Nick





Re: memory (session) leaks in perl

2006-08-23 Thread Nick Williams

Firstly, thanks for the in-depth reply! Some thoughts interleaved below...

Rocco Caputo wrote:


On Aug 22, 2006, at 14:06, Nick Williams wrote:


Rocco Caputo wrote:

Do you have a use case where it's impossible to do something  under  
the new behavior?  I'm working under the assumption that a  session  
can always find a way to call sig(YOUR_SIGNAL_HERE =  undef) when  
it's ready to be destroyed.




When it's ready to be destroyed is the key. The new behaviour  
means that sessions need to track that themselves and (in effect)  
manage their own reference counting independent of POE's. Before,  
they could just rely on POE to let them know via _stop. Now, _stop  
is no longer called unless the session clears the sig first. This  is 
just a catch-22. And it leaves a race condition whereby the  session 
exists but has declared it no longer wants the signal.



Sessions already do need to manage their reference counts, at least  
in the sense that they won't exit until they stop watching for  
events.  Signal events are just another kind of event, and the  
semantics were a bit exceptional for some good reasons that don't  
necessarily apply anymore.


If I understand the catch-22 correctly, it's that a session can't  
clear its signal watchers from _stop because those  watchers prevent  
_stop from executing.  If that's the case, I'd like to point out that  
it's not very useful to clear any resources from _stop to begin  
with.  POE will automatically reclaim its resources from the session  
after _stop returns, so any explicit POE cleanup in _stop is an  
expensive no-op.




In my existing code, I'm not cleaning up POE resources - it's *my* 
resources I'm cleaning up in _stop. The point is that _stop no longer 
gets called because of the signal handlers, so I can no longer use _stop 
as a garbage cleanup mechanism similar to DESTROY, since I will by 
definition always have to know when the session is going to be 
destructed (in order to remove signal handlers) and therefore _stop 
becomes superfluous.



To be fair regarding discussions on this list, Jonathan Steinert   
announced the intent to make sig() hold sessions alive in his 19   
October 2005 message titled Nastiness, and wrapping up signal   
reforms.  I replied that day with:


Big change.  I don't mind this; the old semantics of not holding  
a  reference count were tied to _signal, which delivered signals   
without sessions explicitly asking for them.  _signal is gone  
now,  so we can tie the explicit interest of sig() into a  
reference count  to keep the session alive.




Nobody else responded.  17 days later I replied with a public go-  
ahead to make the change.




Yes, I realise that there was this discussion previously. However,  
speaking purely for myself, I didn't understand the impact of this  
at the time, since I wasn't cognizant of the internals of session  
reference counting at the time. Now I've looked at this, and I  can't 
see how the new implementation makes sense.



I can understand how the implementation might be confusing.  The  
released versions since last December have flaws, especially  
regarding reference counting.  In fact I recently committed fixes for  
them while portability testing some of Benjamin Smith's new tests.


My issue is that that the bugzilla that Jonathan was attempting to  
fix is just trivial to fix using existing POE mechanisms of  aliases, 
since there's an easy point at which you know you want to  start the 
persistence of the session, and there's a well-defined  point at 
which you can release the persistence. However, by making  the 
behaviour of persistence implicit within signals, there is  simply no 
way to achieve the opposite effect (automatic garbage  collection). 
The user (the application) must decide at which point  it has no more 
work to do and at that point it can then clear the  signal. And only 
then will POE do it's garbage collection and call  back to the 
application. This just doesn't make sense. Especially  when you 
compare signals in POE with signals in other dispatchers.  Having a 
handler configured for a signal should not make that  process 
persistent.



The point that persistence shouldn't be tied to signals for  
flexibility's sake is the start of a slippery slope.  What would then  
stop us from asserting that some timers should not imply  
persistence?  Input timeouts, for example.  They don't contribute to  
a session's lifespan since they're only relevant as long as there's  
an I/O watcher.  Why then should delay() keep sessions alive?


We're really talking semantics. A delay says (i.e. is documented as) 
call me back at time T (in effect). The time will always happen (by 
definition). So, it makes sense with those semantics that the session 
should stay alive until at least time T.  However a signal (by 
definition) might never happen.




One solution might be to expand the Kernel's APIs for different  
semantic variants of each watcher

Re: signal design discussions from IRC, leading up to 0.33's change of sig() persistence

2006-08-23 Thread Nick Williams

Rocco Caputo wrote:

Attached as a gzipped text file.  Sorry for posting a binary, but I  
couldn't pass up the 3:1 compression.  Please quote relevant parts of  
the discussion if you want to comment on things.  Total time to cull  
and clean this, about 90 minutes.


I hope it explains the motivations and reasoning behind the sig()  
semantics change.  Armed with the full context, we might be able to  
come up with a better and lasting resolution to the signals problems.


Regarding SIGCHLD, I think Philip Gwyn later suggested some form of  
process ID watcher to supplant the signal.  I don't think he proposed  
it on the list, though.



Gosh, thanks for spending that time and providing the discussion, it's 
quite a fair amount of reading and most valuable :-).


To my mind, the initial part of the discussion regarding SIGCHLD is 
completely orthogonal to the later problem discussed of reference 
counts. I'm fine with the way that the SIGHCHLD discussion turned out 
(and btw, in case anyone cares, I'm one of those people that was bitten 
by system() and qx() going wrong when using POE - the reason being that 
I don't just use POE, I sometimes (shock horror) use OTHER perl modules 
too. One doesn't always have control of what those other modules might 
be doing in their depths and system() is one of those things...) :-). We 
have some systems written with POE that use over 200 different modules. 
Tracking downstream modules for their use of system() is just not feasible.


So, the SIGCHLD part good. Now let's move onto the reference counting. 
The discussion implies that the reference counting is neccessary for the 
SIGCHILD reform. Now that's the bit that's confusing me.


10:13 @   hachi : shouldn't a signal handler keep any session 
alive, no matter what?

10:44 @   dngor : Signal handlers don't affect reference counts.
11:01 @   hachi : now that has me puzzled
11:02 @   hachi : signal handlers are IPC, like filehandles... why 
don't they keep sessions alive?


That's a misnomer. A handler isn't an IPC like a filehandle. As has been 
said previously, if you look at UNIX semantics, signals are very very 
different. And BTW, the ultimate example of this is the DIE handler. 
If I put in place a DIE handler, it's because of defensive programming 
(all those external 200 modules :-): I do not EXPECT nor WANT a DIE to 
actually happen. However, if I put in place a DIE handler, my session 
becomes persistent. And there's a possible race condition with me 
removing the DIE handler when I *think* my session is going to die (but 
hasn't yet reached _stop, and so could quite easily still get a DIE) and 
the session really evaporating.


11:05 @   dngor : Requiring interest in a signal to be registered 
explicitly is a relatively new advancement.  Now that we have it, I 
don't see why not.
11:25 @   hachi : well, I think it might have to happen, at least 
in the case of a CHLD handler, because you can't have that signal 
watcher dying off silently on people



So, that last comment is one of the spurs for putting in reference 
counting. I've been misled by reading the RT stuff saying that the 
refcounting was there for the UI_DESTROY problem. Okay. So


I *guess* that the signal watcher logic is only invoked if there's 
someone interested in SIGCHLD. If there's nobody interested in SIGCHLD, 
then the default behaviour can work just fine. Is that true? And then 
the follow-on is that if someone was previously interested in SIGHCHLD 
and then they say they're not, what happens? If the signal handler 
reverts back to normal perl semantics, then I don't see a problem with 
the signal watcher no longer spinning. So, I can't quite see how this 
adds up to requiring persistent sessions. I feel very much that I'm 
missing some understanding here of how the SIGCHLD stuff has been done. 
I'll go away and read code while waiting for others to correct me :-)


Nick


Re: Component::Client::TCP and a flurry of short messages

2006-08-31 Thread Nick Williams

lanas wrote:


Folks,

 Using POE::Component::Client::TCP, I want to send several short
messages to a server.  The server expects each message as a
stand-alone message so that it knows that the first byte is a command,
the second 4 four bytes a data length, etc...

 But when I send 4 short messages one right after the other, the 2nd,
3rd and 4th gets bundled 'automagically' into one TCP transmission,
and this messes the server.  I do not want to touch the server, which
I haven't written anyways.

 So here's how I send the short messages:  


$_[HEAP]-{server}-put($test1)
$_[HEAP]-{server}-put($test2)
$_[HEAP]-{server}-put($test3)
$_[HEAP]-{server}-put($test4)

 Is there a way to make certain that each of these messages gets sent
on its own in a separate TCP transmission and this, without introducing
any delay ?

 

You probably want to look into disabling the Nagle algorithm on your 
socket. Basically this means setsockopt(TCP_NODELAY) on the socket. 
Within POE::Component::Client::TCP, you can get the socket handle within 
the Connected event and set the option there.


Nick.


 If I put a delay between eahc message then each gets sent
separately.

 If I loop around ServerFlushed, sending a message each time
ServerFlushed is call, would I get the desired result ?  I tried in
another setting with ClientFlushed (Component::Server::TCP) and it
still bundled the messages together in one transmission.

 Any help/ideas/suggestions very much appreciated, thanks !

Al
Folks,

 Using POE::Component::Client::TCP, I want to send several short
messages to a server.  The server expects each message as a
stand-alone message so that it knows that the first byte is a command,
the second 4 four bytes a data length, etc...

 But when I send 4 short messages one right after the other, the 2nd,
3rd and 4th gets bundled 'automagically' into one TCP transmission,
and this messes the server.  I do not want to touch the server, which
I haven't written anyways.

 So here's how I send the short messages:  


$_[HEAP]-{server}-put($test1)
$_[HEAP]-{server}-put($test2)
$_[HEAP]-{server}-put($test3)
$_[HEAP]-{server}-put($test4)

 Is there a way to make certain that each of these messages gets sent
on its own in a separate TCP transmission and this, without introducing
any delay ?

 If I put a delay between eahc message then each gets sent
separately.

 If I loop around ServerFlushed, sending a message each time
ServerFlushed is call, would I get the desired result ?  I tried in
another setting with ClientFlushed (Component::Server::TCP) and it
still bundled the messages together in one transmission.

 Any help very much appreciated, thanks !

Al
 





Re: Brace yourself. POE 0.38 is uploaded to PAUSE.

2006-09-19 Thread Nick Williams

I now have a new problem (don't I always ;-).

ReadLine has a modification that I didn't spot earlier (due to our 
inability to use the last few releases) that doesn't make sense to me. 
The change labelled r2098 (which went into 0.37, I believe) does this:


 2006-09-05 01:41:11 (r2098) by rcaputo; poe/lib/POE/Wheel/ReadLine.pm M

   A cheezy hack to avoid destroying Wheel::ReadLine instances from
   within POE::Kernel's space. A proper fix would be to somehow break
   this wheel's circular references to $self so that DESTROY is
   triggered immediately when the user destroys the objects' last
   references.


I really really don't understand this. The hack is within DESTROY (i.e. 
it's within the code that's called when the wheel is evaporating: by 
definition there are no more references). The hack says if we're 
evaporating and our parent session has already left the building, then 
we will not do proper DESTROY semantics but will instead return. An 
important result of this is that we won't bother resetting the terminal 
mode back to normal. Which means that quite often after using this 
module, the terminal will be screwed up. This isn't good. A quick hack 
fix would be to always restore the terminal state before we hit the 
conditional return. But then it leads me into where I don't understand: 
why would we not want to do all of the cleanup? Even if the parent is 
poe_kernel (i.e. our real session parent has already departed), we can 
still do cleanup. We're in the DESTROY handler! Does it hurt to do any 
of that cleanup? Is the comment saying something else? I don't 
understand the reasoning behind this


Nick


Rocco Caputo wrote:

You have a few hours to perhaps a day or two to prepare yourself for  
the onslaught of goodness encapsulated in this release.  Perhaps most  
significantly, the two changes you've been waiting for all week (if  
not longer):


+ The sig() reference count has been removed.  There will be much  
rejoicing, and probably some gnashing of teeth.


+ sig_child($pid, $event) was introduced.  It waits for an explicit  
process ID.  It holds a session reference count.  It automatically  
clears after the specified process has been reaped and the event has  
been delivered.


But that's not all.  Other people were busy improving POE while I was  
distracted by signals fixes.  Give a big shout out to:


+ Apocalypse made alias_resolve() failures non-fatal when certain  
assertions are enabled.  Rob Bloodgood reported this problem, and  
persisted in making sure it was fixed.


+ Vanilla Perl test failures were worked around.  That distribution  
is highly experimental.  Its developers don't recommend its use.  And  
it isn't bundled with Win32::Console, needed by the Wheel::Run  
tests.  So those tests are skipped if that module isn't installed.


+ Martijn Van Beers documented some hook methods in POE::Session,  
improving POE's kwalitee and passing the features on to you!


+ Matt Sickler applied a doc patch for TRACE_STATISTICS, submitted by  
Joel Bernsein.


And some 0.37 test failures were fixed.  And probably other stuff I  
forgot.  That's okay, though.  There's a CHANGES file inside the  
tarball, and it'll be more than happy to explain everything in much  
greater detail.






Re: POE::Component::Server::TCP bug fixes, possibly incompatible

2009-07-16 Thread Nick Williams
Regarding the passing of the socket into clientconnected - I've wished for
this in the past, in order to be able to modify TCP options on the socket,
which didn't seem possible in the past... It would be nice if that was
possible to get at this (either via some available API which I just haven't
noticed, or if these patches provide it at clientconnected time).

Cheers,
Nick.

On Thu, Jul 16, 2009 at 12:06 PM, Chris 'BinGOs' Williams 
ch...@bingosnet.co.uk wrote:

 On Wed, Jul 15, 2009 at 06:59:12PM -0800, Michael Fowler wrote:
  On Wed, Jul 15, 2009 at 04:08:48AM -0400, Rocco Caputo wrote:
   For starters, $_[ARG0] isn't guaranteed to contain anything in
 particular.
 
  Well, it's guaranteed to contain whatever was passed as the 'args'
  argument to the POE::Session constructor, right?  When the session is
  constructed, 'args' is [ $socket, $client_args ].  That 'args' value
  needs to remain, because the POE::Wheel::ReadWrite constructor needs it.
  Having ClientConnected then mirror _start in terms of arguments seems
  reasonable.
 
 
   I think you're almost right.  The correct behavior would be for
   ClientArgs to align with @_[ARG0..$#_].  This still breaks current
 code,
   but it's cleaner.
 
  Well, I don't mind breaking old code, but I think ARG0 being the socket
  should be preserved.  Reaching into $heap-{client}-get_input_handle
  seems awkward.  Then again, perhaps it's breaking an abstraction to have
  direct access to the socket outside of POE::Wheel::ReadWrite.
 
  The code I have that actually needs it would benefit from the clarity of
  having the socket passed as ARG0.  Whether or not this breaks some
  possible future change in something...
 
  --
  Michael Fowler
  www.shoebox.net

 First off, thanks for all the patches, I've applied them all apart
 from this one.

 And the main reason for that is deciding what is the best course of
 action.

 ( I have no vested interest in POE::Component::Server::TCP myself
  so can have a non-partisan view ).

 There is a difference between the documented behaviour and the actual
 behaviour.

 I, personally, can't see the need to pass the socket object to the
 ClientConnected handler, and without any evidence whatsoever to
 substantiate my claim :) I'd suggest that no one actually uses
 the socket.

 ClientConnected would be used to send any initial text to the client
 which one would usually use $_[HEAP]{client} for.

 Similarly, one might want to find out the TCP connection details,
 which are again in the heap $_[HEAP]{remote_ip}, etc.

 My pennyworth.

 Anyways, I see three options:

 a). Make the functionality match the documentation;

 b). Make the documentation match the functionality;

 c). Do what dngor suggests and flatten ClientArgs, forget the socket
and document as such.

 Cheers,

 --
 Chris Williams
 aka BinGOs
 PGP ID 0x4658671F
 http://www.gumbynet.org.uk
 ==