r77163 - in /branches/upstream/libpoe-component-resolver-perl/current: CHANGES MANIFEST META.yml Makefile.PL README README.mkdn dist.ini lib/POE/Component/Resolver.pm lib/POE/Component/Resolver/ lib/POE/Component/Resolver/Sidecar.pm t/01-basic.t

gregoa at users.alioth.debian.org gregoa at users.alioth.debian.org
Tue Jul 5 18:13:03 UTC 2011


Author: gregoa
Date: Tue Jul  5 18:13:01 2011
New Revision: 77163

URL: http://svn.debian.org/wsvn/pkg-perl/?sc=1&rev=77163
Log:
[svn-upgrade] new version libpoe-component-resolver-perl (0.912)

Added:
    branches/upstream/libpoe-component-resolver-perl/current/lib/POE/Component/Resolver/
    branches/upstream/libpoe-component-resolver-perl/current/lib/POE/Component/Resolver/Sidecar.pm
Modified:
    branches/upstream/libpoe-component-resolver-perl/current/CHANGES
    branches/upstream/libpoe-component-resolver-perl/current/MANIFEST
    branches/upstream/libpoe-component-resolver-perl/current/META.yml
    branches/upstream/libpoe-component-resolver-perl/current/Makefile.PL
    branches/upstream/libpoe-component-resolver-perl/current/README
    branches/upstream/libpoe-component-resolver-perl/current/README.mkdn
    branches/upstream/libpoe-component-resolver-perl/current/dist.ini
    branches/upstream/libpoe-component-resolver-perl/current/lib/POE/Component/Resolver.pm
    branches/upstream/libpoe-component-resolver-perl/current/t/01-basic.t

Modified: branches/upstream/libpoe-component-resolver-perl/current/CHANGES
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-resolver-perl/current/CHANGES?rev=77163&op=diff
==============================================================================
--- branches/upstream/libpoe-component-resolver-perl/current/CHANGES (original)
+++ branches/upstream/libpoe-component-resolver-perl/current/CHANGES Tue Jul  5 18:13:01 2011
@@ -1,3 +1,48 @@
+================================
+2011-05-03 22:38:41 -0400 v0_912
+================================
+
+  commit d0c8a4b0fbf6c6e8e86d83790941efe84d176ba4
+  Author: Rocco Caputo <rcaputo at cpan.org>
+  Date:   Tue May 3 22:38:41 2011 -0400
+  
+    Prepare for next release.
+
+  commit f8d05b1ef5f76133b3c59500d720eed1a074fdc9
+  Author: Rocco Caputo <rcaputo at cpan.org>
+  Date:   Tue May 3 22:38:14 2011 -0400
+  
+    Relying upon DESTROY wasn't reliable. Add a shutdown() method.
+
+  commit f676b39c5fb373b4c83105415e7bb532556ea875
+  Author: Rocco Caputo <rcaputo at cpan.org>
+  Date:   Sun Apr 24 16:28:04 2011 -0400
+  
+    Remove unused GetAddrInfo imports from Sidecar.pm.
+
+  commit 22387e0e157e5cb473314727e0752380da9d8fe6
+  Author: Rocco Caputo <rcaputo at cpan.org>
+  Date:   Sun Apr 24 16:15:13 2011 -0400
+  
+    Add sidecar processes to reduce this component's memory footprint.
+    Prompted by Karen_m's memory issues, and recommended by gcola,
+    Hinrik, and Apocalypse on irc.perl.org #poe. You people rock! :)
+
+  commit faa1588e8a7417b20c3745490e50033bcc744f54
+  Author: Rocco Caputo <rcaputo at cpan.org>
+  Date:   Sun Apr 24 15:48:39 2011 -0400
+  
+    Keep sidecar processes around longer, and provide an idle_timeout
+    constructor parameter to override just how long that is. This is a
+    partial response to Karen_m's report of PID and memory churn
+    introduced by lots of forking.
+
+  commit 1acb4707244468521c7712bc3f410fc72fa5df08
+  Author: Rocco Caputo <rcaputo at cpan.org>
+  Date:   Mon Feb 21 09:15:20 2011 -0500
+  
+    Increase pedantry to mollify assertions. 
+
 ================================
 2011-02-20 22:58:16 -0500 v0_911
 ================================

Modified: branches/upstream/libpoe-component-resolver-perl/current/MANIFEST
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-resolver-perl/current/MANIFEST?rev=77163&op=diff
==============================================================================
--- branches/upstream/libpoe-component-resolver-perl/current/MANIFEST (original)
+++ branches/upstream/libpoe-component-resolver-perl/current/MANIFEST Tue Jul  5 18:13:01 2011
@@ -8,6 +8,7 @@
 README.mkdn
 dist.ini
 lib/POE/Component/Resolver.pm
+lib/POE/Component/Resolver/Sidecar.pm
 t/000-report-versions.t
 t/01-basic.t
 t/release-pod-coverage.t

Modified: branches/upstream/libpoe-component-resolver-perl/current/META.yml
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-resolver-perl/current/META.yml?rev=77163&op=diff
==============================================================================
--- branches/upstream/libpoe-component-resolver-perl/current/META.yml (original)
+++ branches/upstream/libpoe-component-resolver-perl/current/META.yml Tue Jul  5 18:13:01 2011
@@ -6,14 +6,14 @@
 configure_requires:
   ExtUtils::MakeMaker: 6.31
 dynamic_config: 0
-generated_by: 'Dist::Zilla version 4.200000, CPAN::Meta::Converter version 2.102400'
+generated_by: 'Dist::Zilla version 4.200004, CPAN::Meta::Converter version 2.102400'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
   version: 1.4
 name: POE-Component-Resolver
 requires:
-  POE: 1.299
+  POE: 1.311
   Scalar::Util: 1.23
   Socket::GetAddrInfo: 0.19
   Storable: 2.18
@@ -21,4 +21,4 @@
   Time::HiRes: 1.9711
 resources:
   repository: git://github.com/rcaputo/poe-component-resolver.git
-version: 0.911
+version: 0.912

Modified: branches/upstream/libpoe-component-resolver-perl/current/Makefile.PL
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-resolver-perl/current/Makefile.PL?rev=77163&op=diff
==============================================================================
--- branches/upstream/libpoe-component-resolver-perl/current/Makefile.PL (original)
+++ branches/upstream/libpoe-component-resolver-perl/current/Makefile.PL Tue Jul  5 18:13:01 2011
@@ -20,14 +20,14 @@
   'LICENSE' => 'perl',
   'NAME' => 'POE::Component::Resolver',
   'PREREQ_PM' => {
-    'POE' => '1.299',
+    'POE' => '1.311',
     'Scalar::Util' => '1.23',
     'Socket::GetAddrInfo' => '0.19',
     'Storable' => '2.18',
     'Test::More' => '0.96',
     'Time::HiRes' => '1.9711'
   },
-  'VERSION' => '0.911',
+  'VERSION' => '0.912',
   'test' => {
     'TESTS' => 't/*.t'
   }

Modified: branches/upstream/libpoe-component-resolver-perl/current/README
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-resolver-perl/current/README?rev=77163&op=diff
==============================================================================
--- branches/upstream/libpoe-component-resolver-perl/current/README (original)
+++ branches/upstream/libpoe-component-resolver-perl/current/README Tue Jul  5 18:13:01 2011
@@ -2,7 +2,7 @@
     POE::Component::Resolver - A non-blocking getaddrinfo() resolver
 
 VERSION
-    version 0.911
+    version 0.912
 
 SYNOPSIS
             #!/usr/bin/perl
@@ -15,7 +15,8 @@
 
             my $r = POE::Component::Resolver->new(
                     max_resolvers => 8,
-                    af_order => [ AF_INET6, AF_INET ],
+                    idle_timeout  => 5,
+                    af_order      => [ AF_INET6, AF_INET ],
             );
 
             my @hosts = qw( ipv6-test.com );
@@ -82,10 +83,13 @@
                     af_order => [ AF_INET6 ]
             );
 
+    "idle_timeout" determines how long to keep idle resolver subprocesses
+    before cleaning them up, in seconds. It defaults to 15.0 seconds.
+
     "max_resolvers" controls the component's parallelism by defining the
     maximum number of sidecar processes to manage. It defaults to 8, but
-    fewer or more processes can be configured depending on usage
-    requirements.
+    fewer or more processes can be configured depending on the resources you
+    have available and the amount of parallelism you require.
 
             # One at a time, but without the pesky blocking.
             my $r3 = POE::Component::Resolver->new( max_resolvers => 1 );
@@ -111,6 +115,15 @@
     "misc" is optional continuation data that will be passed back in the
     response. It may contain any type of data the application requires.
 
+   shutdown
+    Shut down the resolver. POE::Component::Resolver retains resources
+    including child processes for up to "idle_timeout" seconds. This may
+    keep programs running up to "idle_timeout" seconds longer than they
+    should.
+
+    POE::Component::Resolver will release its resources (including child
+    processes) when its shutdown() method is called.
+
    unpack_addr
     In scalar context, unpack_addr($response_addr_hashref) returns the addr
     element of $response_addr_hashref in a numeric form appropriate for the
@@ -143,11 +156,6 @@
     unpack_addr() returns bleak emptiness on failure, regardless of context.
     You can check for undef return.
 
-   DESTROY
-    This component is shut down when it's destroyed, following Perl's rules
-    for object destruction. Any pending requests are canceled, and their
-    responses will be errors.
-
   PUBLIC EVENTS
    resolver_response
     The resolver response event includes three parameters.
@@ -195,6 +203,28 @@
 
     There is no way to cancel a pending request.
 
+TROUBLESHOOTING
+  programs linger for several seconds before exiting
+    Programs should shutdown() their POE::Component::Resolver objects when
+    they are through needing asynchronous DNS resolution. Programs should
+    additionally destroy their resolvers if they intend to run awhile and
+    want to reuse the memory they consume.
+
+    In some cases, it may be necessary to shutdown components that perform
+    asynchronous DNS using POE::Component::Resolver... such as
+    POE::Component::IRC, POE::Component::Client::Keepalive and
+    POE::Component::Client::HTTP.
+
+    By default, the resolver subprocesses hang around for idle_timeout,
+    which defaults to 15.0 seconds. Destroying the Resolver object will
+    clean up the process pool. Assuming only that is keeping the event loop
+    active, the program will then exit cleanly.
+
+    Alternatively, reduce idle_timeout to a more manageable number, such as
+    5.0 seconds.
+
+    Otherwise something else may also be keeping the event loop active.
+
 LICENSE
     Except where otherwise noted, this distribution is Copyright 2011 by
     Rocco Caputo. All rights reserved. This distribution is free software;

Modified: branches/upstream/libpoe-component-resolver-perl/current/README.mkdn
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-resolver-perl/current/README.mkdn?rev=77163&op=diff
==============================================================================
--- branches/upstream/libpoe-component-resolver-perl/current/README.mkdn (original)
+++ branches/upstream/libpoe-component-resolver-perl/current/README.mkdn Tue Jul  5 18:13:01 2011
@@ -4,7 +4,7 @@
 
 # VERSION
 
-version 0.911
+version 0.912
 
 # SYNOPSIS
 
@@ -18,7 +18,8 @@
 
 	my $r = POE::Component::Resolver->new(
 		max_resolvers => 8,
-		af_order => [ AF_INET6, AF_INET ],
+		idle_timeout  => 5,
+		af_order      => [ AF_INET6, AF_INET ],
 	);
 
 	my @hosts = qw( ipv6-test.com );
@@ -88,10 +89,13 @@
 		af_order => [ AF_INET6 ]
 	);
 
+"idle_timeout" determines how long to keep idle resolver subprocesses
+before cleaning them up, in seconds.  It defaults to 15.0 seconds.
+
 "max_resolvers" controls the component's parallelism by defining the
 maximum number of sidecar processes to manage.  It defaults to 8, but
-fewer or more processes can be configured depending on usage
-requirements.
+fewer or more processes can be configured depending on the resources
+you have available and the amount of parallelism you require.
 
 	# One at a time, but without the pesky blocking.
 	my $r3 = POE::Component::Resolver->new( max_resolvers => 1 );
@@ -118,6 +122,16 @@
 
 "misc" is optional continuation data that will be passed back in the
 response.  It may contain any type of data the application requires.
+
+### shutdown
+
+Shut down the resolver.  POE::Component::Resolver retains resources
+including child processes for up to "idle_timeout" seconds.  This may
+keep programs running up to "idle_timeout" seconds longer than they
+should.
+
+POE::Component::Resolver will release its resources (including child
+processes) when its shutdown() method is called.
 
 ### unpack_addr
 
@@ -152,12 +166,6 @@
 unpack_addr() returns bleak emptiness on failure, regardless of
 context.  You can check for undef return.
 
-### DESTROY
-
-This component is shut down when it's destroyed, following Perl's
-rules for object destruction.  Any pending requests are canceled, and
-their responses will be errors.
-
 ## PUBLIC EVENTS
 
 ### resolver_response
@@ -207,6 +215,30 @@
 
 There is no way to cancel a pending request.
 
+# TROUBLESHOOTING
+
+## programs linger for several seconds before exiting
+
+Programs should shutdown() their POE::Component::Resolver objects when
+they are through needing asynchronous DNS resolution.  Programs should
+additionally destroy their resolvers if they intend to run awhile and
+want to reuse the memory they consume.
+
+In some cases, it may be necessary to shutdown components that perform
+asynchronous DNS using POE::Component::Resolver... such as
+POE::Component::IRC, POE::Component::Client::Keepalive and
+POE::Component::Client::HTTP.
+
+By default, the resolver subprocesses hang around for idle_timeout,
+which defaults to 15.0 seconds.  Destroying the Resolver object will
+clean up the process pool.  Assuming only that is keeping the event
+loop active, the program will then exit cleanly.
+
+Alternatively, reduce idle_timeout to a more manageable number, such
+as 5.0 seconds.
+
+Otherwise something else may also be keeping the event loop active.
+
 # LICENSE
 
 Except where otherwise noted, this distribution is Copyright 2011 by

Modified: branches/upstream/libpoe-component-resolver-perl/current/dist.ini
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-resolver-perl/current/dist.ini?rev=77163&op=diff
==============================================================================
--- branches/upstream/libpoe-component-resolver-perl/current/dist.ini (original)
+++ branches/upstream/libpoe-component-resolver-perl/current/dist.ini Tue Jul  5 18:13:01 2011
@@ -1,16 +1,16 @@
 name              = POE-Component-Resolver
-version           = 0.911
+version           = 0.912
 author            = Rocco Caputo <rcaputo at cpan.org>
 license           = Perl_5
 copyright_holder  = Rocco Caputo
 
 [Prereqs]
-POE                    = 1.299
+POE                    = 1.311
 Scalar::Util           = 1.23
+Socket::GetAddrInfo    = 0.19
 Storable               = 2.18
-Socket::GetAddrInfo    = 0.19
+Test::More             = 0.96
 Time::HiRes            = 1.9711
-Test::More             = 0.96
 
 [Repository]
 git_remote = gh

Modified: branches/upstream/libpoe-component-resolver-perl/current/lib/POE/Component/Resolver.pm
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-resolver-perl/current/lib/POE/Component/Resolver.pm?rev=77163&op=diff
==============================================================================
--- branches/upstream/libpoe-component-resolver-perl/current/lib/POE/Component/Resolver.pm (original)
+++ branches/upstream/libpoe-component-resolver-perl/current/lib/POE/Component/Resolver.pm Tue Jul  5 18:13:01 2011
@@ -1,20 +1,16 @@
 package POE::Component::Resolver;
 BEGIN {
-  $POE::Component::Resolver::VERSION = '0.911';
+  $POE::Component::Resolver::VERSION = '0.912';
 }
 
 use warnings;
 use strict;
 
 use POE qw(Wheel::Run Filter::Reference);
-use Scalar::Util qw(weaken);
 use Carp qw(croak);
-use Storable qw(nfreeze thaw);
-use Socket::GetAddrInfo qw(
-	:newapi getaddrinfo getnameinfo NI_NUMERICHOST NI_NUMERICSERV
-);
 use Time::HiRes qw(time);
 use Socket qw(unpack_sockaddr_in AF_INET AF_INET6);
+use Socket::GetAddrInfo qw(:newapi getnameinfo NI_NUMERICHOST NI_NUMERICSERV);
 
 use Exporter;
 use base 'Exporter';
@@ -29,6 +25,7 @@
 	my %args = @args;
 
 	my $max_resolvers = delete($args{max_resolvers}) || 8;
+	my $idle_timeout  = delete($args{idle_timeout})  || 15;
 
 	my $af_order = delete($args{af_order});
 	if (defined $af_order and @$af_order) {
@@ -57,6 +54,8 @@
 		inline_states => {
 			_start           => \&_poe_start,
 			_stop            => sub { undef },  # for ASSERT_DEFAULT
+			_parent          => sub { undef },  # for ASSERT_DEFAULT
+			_child           => sub { undef },  # for ASSERT_DEFAULT
 			request          => \&_poe_request,
 			shutdown         => \&_poe_shutdown,
 			sidecar_closed   => \&_poe_sidecar_closed,
@@ -66,13 +65,30 @@
 			sidecar_eject    => \&_poe_sidecar_eject,
 			sidecar_attach   => \&_poe_sidecar_attach,
 		},
-		args => [ "$self", $max_resolvers, $af_order ],
+		heap => {
+			af_order        => $af_order,
+			alias           => "$self",
+			idle_timeout    => $idle_timeout,
+			last_request_id => 0,
+			max_resolvers   => $max_resolvers,
+			requests        => { },
+			sidecar_ring    => [ ],
+		}
 	);
 
 	return $self;
 }
 
 sub DESTROY {
+	my $self = shift;
+
+	# Can't resolve the session: it must already be gone.
+	return unless $poe_kernel->alias_resolve("$self");
+
+	$poe_kernel->call("$self", "shutdown");
+}
+
+sub shutdown {
 	my $self = shift;
 
 	# Can't resolve the session: it must already be gone.
@@ -143,6 +159,9 @@
 		sidecar_id  => $next_sidecar->ID(),
 	};
 
+	# No ejecting until we're done.
+	$kernel->delay(sidecar_eject => undef);
+
 	return 1;
 }
 
@@ -150,18 +169,9 @@
 # processes, which are owned and managed by that session.
 
 sub _poe_start {
-	my ($kernel, $heap, $alias, $max_resolvers, $af_order) = @_[
-		KERNEL, HEAP, ARG0..ARG2
-	];
-
-	$heap->{af_order}        = $af_order;
-	$heap->{requests}        = {};
-	$heap->{last_reuqest_id} = 0;
-	$heap->{alias}           = $alias;
-	$heap->{max_resolvers}   = $max_resolvers;
-	$heap->{sidecar_ring}    = [];
-
-	$kernel->alias_set($alias);
+	my ($kernel, $heap) = @_[KERNEL, HEAP];
+
+	$kernel->alias_set($heap->{alias});
 
 	_poe_setup_sidecar_ring($kernel, $heap);
 
@@ -176,13 +186,23 @@
 
 	return if $heap->{shutdown};
 
-	while (scalar keys %{$heap->{sidecar}} < $heap->{max_resolvers}) {
+	while (scalar(keys %{$heap->{sidecar}}) < $heap->{max_resolvers}) {
 		my $sidecar = POE::Wheel::Run->new(
 			StdioFilter  => POE::Filter::Reference->new(),
 			StdoutEvent  => 'sidecar_response',
 			StderrEvent  => 'sidecar_error',
 			CloseEvent   => 'sidecar_closed',
-			Program      => \&_sidecar_code,
+			Program      => (
+				($^O eq "MSWin32")
+				? \&POE::Component::Resolver::Sidecar::main
+				: [
+					$^X,
+					(map { "-I$_" } @INC),
+					'-MPOE::Component::Resolver::Sidecar',
+					'-e',
+					'POE::Component::Resolver::Sidecar->main()'
+				]
+			),
 		);
 
 		$heap->{sidecar}{$sidecar->PID}   = $sidecar;
@@ -190,47 +210,6 @@
 		push @{$heap->{sidecar_ring}}, $sidecar;
 
 		$kernel->sig_child($sidecar->PID(), "sidecar_signal");
-	}
-}
-
-# Internal helper sub.  This is the code that will run within each
-# sidecar process.  It accepts requests from the main process, runs
-# the blocking getaddrinfo() for each request, and returns responses.
-#
-# TODO - This would be more efficient as a stand-alone Perl program.
-# The program at large can be quite... large... and forking it for
-# just this snip of code seems inefficient.
-
-sub _sidecar_code {
-	my $filter = POE::Filter::Reference->new();
-	my $buffer = "";
-	my $read_length;
-
-	binmode(STDOUT);
-	use bytes;
-
-	while (1) {
-		if (defined $read_length) {
-			if (length($buffer) >= $read_length) {
-				my $request = thaw(substr($buffer, 0, $read_length, ""));
-				$read_length = undef;
-
-				my ($request_id, $host, $service, $hints) = @$request;
-				my ($err, @addrs) = getaddrinfo($host, $service, $hints);
-
-				my $streamable = nfreeze( [ $request_id, $err, \@addrs ] );
-				print length($streamable), chr(0), $streamable;
-
-				next;
-			}
-		}
-		elsif ($buffer =~ s/^(\d+)\0//) {
-			$read_length = $1;
-			next;
-		}
-
-		my $octets_read = sysread(STDIN, $buffer, 4096, length($buffer));
-		last unless $octets_read;
 	}
 }
 
@@ -374,7 +353,9 @@
 	$kernel->refcount_decrement($request_rec->{sender}, __PACKAGE__);
 
 	# No more requests?  Consder detaching sidecar.
-	$kernel->yield("sidecar_eject") unless scalar keys %{$heap->{requests}};
+	$kernel->delay(sidecar_eject => $heap->{idle_timeout}) unless (
+		scalar keys %{$heap->{requests}}
+	);
 }
 
 # A sidecar process has exited.  Clean up its resources, and attach a
@@ -447,7 +428,7 @@
 
 =head1 VERSION
 
-version 0.911
+version 0.912
 
 =head1 SYNOPSIS
 
@@ -461,7 +442,8 @@
 
 	my $r = POE::Component::Resolver->new(
 		max_resolvers => 8,
-		af_order => [ AF_INET6, AF_INET ],
+		idle_timeout  => 5,
+		af_order      => [ AF_INET6, AF_INET ],
 	);
 
 	my @hosts = qw( ipv6-test.com );
@@ -531,10 +513,13 @@
 		af_order => [ AF_INET6 ]
 	);
 
+"idle_timeout" determines how long to keep idle resolver subprocesses
+before cleaning them up, in seconds.  It defaults to 15.0 seconds.
+
 "max_resolvers" controls the component's parallelism by defining the
 maximum number of sidecar processes to manage.  It defaults to 8, but
-fewer or more processes can be configured depending on usage
-requirements.
+fewer or more processes can be configured depending on the resources
+you have available and the amount of parallelism you require.
 
 	# One at a time, but without the pesky blocking.
 	my $r3 = POE::Component::Resolver->new( max_resolvers => 1 );
@@ -562,6 +547,16 @@
 "misc" is optional continuation data that will be passed back in the
 response.  It may contain any type of data the application requires.
 
+=head3 shutdown
+
+Shut down the resolver.  POE::Component::Resolver retains resources
+including child processes for up to "idle_timeout" seconds.  This may
+keep programs running up to "idle_timeout" seconds longer than they
+should.
+
+POE::Component::Resolver will release its resources (including child
+processes) when its shutdown() method is called.
+
 =head3 unpack_addr
 
 In scalar context, unpack_addr($response_addr_hashref) returns the
@@ -595,12 +590,6 @@
 unpack_addr() returns bleak emptiness on failure, regardless of
 context.  You can check for undef return.
 
-=head3 DESTROY
-
-This component is shut down when it's destroyed, following Perl's
-rules for object destruction.  Any pending requests are canceled, and
-their responses will be errors.
-
 =head2 PUBLIC EVENTS
 
 =head3 resolver_response
@@ -654,6 +643,30 @@
 
 There is no way to cancel a pending request.
 
+=head1 TROUBLESHOOTING
+
+=head2 programs linger for several seconds before exiting
+
+Programs should shutdown() their POE::Component::Resolver objects when
+they are through needing asynchronous DNS resolution.  Programs should
+additionally destroy their resolvers if they intend to run awhile and
+want to reuse the memory they consume.
+
+In some cases, it may be necessary to shutdown components that perform
+asynchronous DNS using POE::Component::Resolver... such as
+POE::Component::IRC, POE::Component::Client::Keepalive and
+POE::Component::Client::HTTP.
+
+By default, the resolver subprocesses hang around for idle_timeout,
+which defaults to 15.0 seconds.  Destroying the Resolver object will
+clean up the process pool.  Assuming only that is keeping the event
+loop active, the program will then exit cleanly.
+
+Alternatively, reduce idle_timeout to a more manageable number, such
+as 5.0 seconds.
+
+Otherwise something else may also be keeping the event loop active.
+
 =head1 LICENSE
 
 Except where otherwise noted, this distribution is Copyright 2011 by

Added: branches/upstream/libpoe-component-resolver-perl/current/lib/POE/Component/Resolver/Sidecar.pm
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-resolver-perl/current/lib/POE/Component/Resolver/Sidecar.pm?rev=77163&op=file
==============================================================================
--- branches/upstream/libpoe-component-resolver-perl/current/lib/POE/Component/Resolver/Sidecar.pm (added)
+++ branches/upstream/libpoe-component-resolver-perl/current/lib/POE/Component/Resolver/Sidecar.pm Tue Jul  5 18:13:01 2011
@@ -1,0 +1,107 @@
+package POE::Component::Resolver::Sidecar;
+BEGIN {
+  $POE::Component::Resolver::Sidecar::VERSION = '0.912';
+}
+
+use warnings;
+use strict;
+
+use Storable qw(nfreeze thaw);
+
+use Socket::GetAddrInfo qw(:newapi getaddrinfo);
+
+sub main {
+	my $buffer = "";
+	my $read_length;
+
+	binmode(STDIN);
+	binmode(STDOUT);
+	select STDOUT; $| = 1;
+
+	use bytes;
+
+	while (1) {
+		if (defined $read_length) {
+			if (length($buffer) >= $read_length) {
+				my $request = thaw(substr($buffer, 0, $read_length, ""));
+				$read_length = undef;
+
+				my ($request_id, $host, $service, $hints) = @$request;
+				my ($err, @addrs) = getaddrinfo($host, $service, $hints);
+
+				my $streamable = nfreeze( [ $request_id, $err, \@addrs ] );
+				my $stream = length($streamable) . chr(0) . $streamable;
+
+				my $octets_wrote = syswrite(STDOUT, $stream);
+				die $! unless $octets_wrote == length($stream);
+
+				next;
+			}
+		}
+		elsif ($buffer =~ s/^(\d+)\0//) {
+			$read_length = $1;
+			next;
+		}
+
+		my $octets_read = sysread(STDIN, $buffer, 4096, length($buffer));
+		last unless $octets_read;
+	}
+
+	exit 0;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+POE::Component::Resolver::Sidecar - delegate subprocess to call getaddrinfo()
+
+=head1 VERSION
+
+version 0.912
+
+=head1 SYNOPSIS
+
+Used internally by POE::Component::Resolver.
+
+=head1 DESCRIPTION
+
+POE::Component::Resolver creates subprocesses to call getaddrinfo() so
+that the main program doesn't block during that time.
+
+The actual getaddrinfo() calling code is abstracted into this module
+so it can be run in a separate executable program.  This reduces the
+memory footprint of forking the entire main process for just
+getaddrinfo().
+
+It's a strong, useful pattern that other POE::Components have
+implemented before.  POE::Quickie does it generically.
+POE::Component::SimpleDBI and POE::Component::EasyDBI do it so their
+DBI subprocesses are relatively lightweight.
+
+=head2 main
+
+The main code to read POE::Component::Resolver requests from STDIN and
+write getaddrinfo() responses to STDOUT.
+
+=head1 SEE ALSO
+
+L<POE::Component::Generic> is one generic implementation of this
+pattern.
+
+L<POE::Quickie> is another generic implementation of this pattern.
+
+=head1 BUGS
+
+None known.
+
+=head1 LICENSE
+
+Except where otherwise noted, this distribution is Copyright 2011 by
+Rocco Caputo.  All rights reserved.  This distribution is free
+software; you may redistribute it and/or modify it under the same
+terms as Perl itself.
+
+=cut

Modified: branches/upstream/libpoe-component-resolver-perl/current/t/01-basic.t
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-resolver-perl/current/t/01-basic.t?rev=77163&op=diff
==============================================================================
--- branches/upstream/libpoe-component-resolver-perl/current/t/01-basic.t (original)
+++ branches/upstream/libpoe-component-resolver-perl/current/t/01-basic.t Tue Jul  5 18:13:01 2011
@@ -11,6 +11,7 @@
 
 my $r4 = POE::Component::Resolver->new(
 	max_resolvers => 1,
+	idle_timeout  => 1,
 	af_order      => [ AF_INET ],
 );
 
@@ -30,16 +31,19 @@
 if ($has_ipv6) {
 	$r6 = POE::Component::Resolver->new(
 		max_resolvers => 1,
+		idle_timeout  => 1,
 		af_order      => [ AF_INET6 ],
 	);
 
 	$r46 = POE::Component::Resolver->new(
 		max_resolvers => 1,
+		idle_timeout  => 1,
 		af_order      => [ AF_INET, AF_INET6 ],
 	);
 
 	$r64 = POE::Component::Resolver->new(
 		max_resolvers => 1,
+		idle_timeout  => 1,
 		af_order      => [ AF_INET6, AF_INET ],
 	);
 }




More information about the Pkg-perl-cvs-commits mailing list