Subject: | session leak in IKC Client Lite |
Date: | Fri, 11 Aug 2006 12:30:47 -0500 |
To: | bug-POE-Component-IKC [...] rt.cpan.org |
From: | JT Smith <jt [...] plainblack.com> |
PoCo::IKC::ClientLite is causing a session leak in POE. This is with POE 0.3401 and
PoCo::IKC 0.1802. The basic steps to reproduce are these:
my $remote = create_ikc_client(
port=>12345,
ip=>'127.0.0.1',
name=>rand(100000),
timeout=>10
);
my $result = $remote->post_respond('admin/ping');
$remote->disconnect;
The other end is configured to return the word "pong".
Anyway, when you call this code, it connects and gets the response that it should.
However, when it disconnects it leaves the session open on the POE end. You can end up
with thousands of these open sessions over time.
Though I don't know how to fix it, I believe that I've found out what's causing this bug
on the POE mailing list:
Subject: memory (session) leaks in perl
Date: Wed, 02 Aug 2006 16:44:18 +0100
From: Nick Williams <Nick.Williams@morganstanley.com>
Organization: Morgan Stanley
To: poe@perl.org
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
JT ~ Plain Black
ph: 703-286-2525 ext. 810
fax: 312-264-5382
http://www.plainblack.com
I reject your reality, and substitute my own. ~ Adam Savage