Subject: | [patch] blocking call in UDP server |
The UDP server has a blocking call in it (gethostbyname).
This is undesirable in a event driven framework like POE; the whole system freezes while gethostbyname trundles about finding a DNS server and waiting for a response.
The solution attached gives a new option to turn this off; this gives a significant (5 fold, or thereabouts) throughput improvment in my enviroment (syslog sources not in /etc/hosts; dns server on same lan but not on the same host; nscd running).
A perhaps better solution would be to use POE::Component::Client::DNS to do the lookups (optionally) so that while DNS servers scratch their heads about the answer the rest of the POE system can still run. However, the quick and dirty "just turn it off!!" option was easier to write.
I imagine that the TCP server has the same problem, but that it is less impactful because I expect you do the gethostbyname on accept and not per-message, but (given I'm doing UDP stuff at the point I ran into the problem) I haven't checked.
Note: this patch was written against 1.02; I've just imported 1.03 into our CVS repository and done the approprate merge magic. It builds OK and passess the tests on:
RedHat-3FC-i386
RedHat-3AS-ia32
RedHat-FC.4-i386
RedHat-EL.4-i386
with the vendor perl.
Index: package.xml
===================================================================
RCS file: /cvsroot/packages/POE-Component-Server-Syslog/package.xml,v
retrieving revision 1.7
retrieving revision 1.7.2.1
diff -u -r1.7 -r1.7.2.1
--- package.xml 6 Dec 2005 17:51:53 -0000 1.7
+++ package.xml 6 Dec 2005 17:54:50 -0000 1.7.2.1
@@ -1,11 +1,11 @@
<?xml version="1.0"?>
-<!-- $Thus: packages/POE-Component-Server-Syslog/package.xml,v 1.7 2005/12/06 17:51:53 michaelb-repoman Exp $ -->
+<!-- $Thus: packages/POE-Component-Server-Syslog/package.xml,v 1.7.2.1 2005/12/06 17:54:50 michaelb Exp $ -->
<Package xmlns="http://www.eng.demon.net/XML/pbuild">
<Class>cpan</Class>
<Name>POE-Component-Server-Syslog</Name>
<Version>1.03</Version>
- <Release>1</Release>
+ <Release>2_BUG_5464_2_RC1</Release>
<Summary>Perl5 library to provide syslog services to POE</Summary>
<Description>
This component provides very simple syslog services for POE.
Index: POE-Component-Server-Syslog/lib/POE/Component/Server/Syslog/UDP.pm
===================================================================
RCS file: /cvsroot/upstream/POE-Component-Server-Syslog/lib/POE/Component/Server/Syslog/UDP.pm,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.6.1
diff -u -r1.1.1.1 -r1.1.1.1.6.1
--- POE-Component-Server-Syslog/lib/POE/Component/Server/Syslog/UDP.pm 13 Mar 2005 21:08:42 -0000 1.1.1.1
+++ POE-Component-Server-Syslog/lib/POE/Component/Server/Syslog/UDP.pm 6 Dec 2005 17:54:25 -0000 1.1.1.1.6.1
@@ -10,6 +10,7 @@
sub BINDPORT () { 514 }
sub DATAGRAM_MAXLEN () { 1024 } # syslogd defaults to this. as do most
# libc implementations of syslog
+sub DNSLOOKUP () { 1 }
use Params::Validate qw(validate_with);
use Carp qw(carp croak);
@@ -49,6 +50,11 @@
optional => 1,
default => DATAGRAM_MAXLEN,
},
+ DnisLookup => {
+ type => &Params::Validate::SCALAR,
+ optional => 1,
+ default => DNSLOOKUP,
+ },
},
);
@@ -111,10 +117,14 @@
if(defined $records and ref $records eq 'ARRAY') {
foreach my $record (@$records) {
if( ( sockaddr_in( $remote_socket ) )[1]) {
- $record->{host} = gethostbyaddr(
- ( sockaddr_in( $remote_socket ) )[1],
- AF_INET,
- );
+ if ($_[HEAP]->{DnisLookup}) {
+ $record->{host} = gethostbyaddr(
+ ( sockaddr_in( $remote_socket ) )[1],
+ AF_INET,
+ );
+ } else {
+ $record->{host} = inet_ntoa(( sockaddr_in( $remote_socket ) )[1]);
+ }
} else {
$record->{host} = '[unknown]';
}