Subject: | Memory leak of sleepers_list |
Date: | Mon, 5 Sep 2011 16:08:28 +0900 (JST) |
To: | bug-Gearman-Server [...] rt.cpan.org |
From: | marsh_yamazaki [...] yahoo.co.jp |
hello,
Connecting/disconnecting repeatedly from worker cause memory leak @Gearman-Server-1.11.
In on_client_sleep() @Server.pm, Gearman::Server::Client object($cl) is stored in $self->{sleepers_list}{$cd} array, and map is created at $self->{sleepers}{$cd} hash.
In close() @Server/Client.pm, $self->{server}{sleepers}->{job}->{$self} is deleted.
But $self still remains in $self->{server}{sleepers_list}->{$job}.
So connecting/disconnecting from worker increase sleepers_list->{$job} array.
Request $job from client will delete $self->{sleepers}{$func} in _wake_up_some @Server.pm.
But without the request, Gearman::Server::Client object is never deleted.
I think sleepers_list should be cleaned at close().
===
--- /usr/lib/perl5/vendor_perl/5.8.8/Gearman/Server/Client.pm 2009-10-05 10:36:10.000000000 +0900
+++ /tmp/Client.pm 2011-09-05 15:18:38.000000000 +0900
@@ -92,9 +92,21 @@
# Remove self from sleepers, otherwise it will be leaked if another worker
# for the job never connects.
my $sleepers = $self->{server}{sleepers};
+ my $sleepers_list = $self->{server}{sleepers_list};
for my $job (@{ $self->{can_do_list} }) {
my $sleeping = $sleepers->{$job};
delete $sleeping->{$self};
+
+ my $new_sleepers_list;
+ for my $client (@{$sleepers_list->{$job}}) {
+ push @{$new_sleepers_list}, $client unless $sleeping->{$client};
+ }
+ if ($new_sleepers_list) {
+ $self->{server}{sleepers_list}->{$job} = $new_sleepers_list;
+ } else {
+ delete $self->{server}{sleepers_list}->{$job};
+ }
+
delete $sleepers->{$job} unless %$sleeping;
}
===
best regard.