Skip Menu |

This queue is for tickets about the Sphinx-Search CPAN distribution.

Report information
The Basics
Id: 41409
Status: resolved
Priority: 0/
Queue: Sphinx-Search

People
Owner: Nobody in particular
Requestors: cpan [...] tty.nl
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: 0.13_01



Subject: [PATCH] use IO::Socket to improve socket operations
the patch makes Sphinx::Search use IO::Socket for the socket operations. (we couldn't find an email address, so we sent you the patch this way)
Subject: sphinx-search.patch
diff --git a/lib/Sphinx/Search.pm b/lib/Sphinx/Search.pm index 67c4a6e..8f3dcb0 100644 --- a/lib/Sphinx/Search.pm +++ b/lib/Sphinx/Search.pm @@ -2,13 +2,15 @@ package Sphinx::Search; use warnings; use strict; + +use base 'Exporter'; + use Carp; use Socket; use Config; use Math::BigInt; -use base 'Exporter'; -use Fcntl qw(:DEFAULT); -use Errno; +use English qw($INPUT_RECORD_SEPARATOR); +use IO::Socket::INET; =head1 NAME @@ -322,61 +324,15 @@ sub _Connect { return $self->{_connection} if $self->{_connection}; # connect socket - my $fp; - socket($fp, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || Carp::croak("socket: ".$!); + my $fp = IO::Socket::INET->new( PeerPort => $self->{"_port"}, + PeerAddr => $self->{"_host"}, + Proto => 'tcp', + Timeout => $self->{"_timeout"}, + ) or croak("Failed to open connection: $!"); binmode($fp, ':bytes'); - my $dest = sockaddr_in($self->{_port}, inet_aton($self->{_host})); - - if ($self->{_timeout}) { - my $flags = fcntl($fp, F_GETFL, 0) or do { - $self->_Error("Can't get flags for socket: $!"); - return 0; - }; - fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or do { - $self->_Error("Can't set flags for socket: $!"); - return 0; - }; - - if (! connect($fp, $dest)) { - if (! $!{EINPROGRESS}) { - $self->_Error("connect to {$self->{_host}}:{$self->{_port}} failed: $!"); - return 0; - } - my $count = 0; - while ($count < 2) { # until timeout or data received - my $vec = ''; - vec($vec, fileno($fp), 1) = 1; - my $n = select($vec, undef, undef, $self->{_timeout}); - if ($n < 0) { - $self->_Error("connection to {$self->{_host}}:{$self->{_port}} failed: $!"); - return 0; - } - elsif ($n == 0) { - $self->_Error("connection to {$self->{_host}}:{$self->{_port}} timed out"); - return 0; - } - else { - my $tmpbuf = 0; - my $ret = recv($fp, $tmpbuf, 4, MSG_PEEK); - last if $tmpbuf; - } - $count++; - } - } - fcntl($fp, F_SETFL, $flags) or do { - $self->_Error("Can't set flags for socket: $!"); - return 0; - }; - } - else { - connect($fp, $dest) or do { - $self->_Error("connection to {$self->{_host}}:{$self->{_port}} failed: $!"); - return 0; - }; - } # check version my $buf = ''; - croak("recv: ".$!) unless defined recv($fp, $buf, 4, 0); + $fp->read($buf, 4) or croak("read failed: $!"); my $v = unpack("N*", $buf); $v = int($v); if($v < 1) { @@ -387,7 +343,7 @@ sub _Connect { $self->{_log}->debug("Sending version") if $debug; # All ok, send my version - send($fp, pack("N", 1),0); + $fp->write( pack( "N", 1 ) ); $self->{_connection} = $fp; @@ -404,18 +360,19 @@ sub _GetResponse { my $fp = shift; my $client_ver = shift; - my $header; - croak("recv: ".$!) unless defined recv($fp, $header, 8, 0); + my $response; + { + # read everything till the end-of-file (close) + local $INPUT_RECORD_SEPARATOR = undef; + $response = $fp->getline; + } + my $header = substr($response, 0, 8, q{}); my ($status, $ver, $len ) = unpack("n2N", $header); - my ($chunk, $response); - while(defined($chunk = <$fp>)) { - $response .= $chunk; - } $self->_Disconnect unless $self->{_persistent_connection}; # check response - if ( !$response || length($response) != $len ) { + if ( length($response) != $len ) { $self->_Error( $len ? "failed to read searchd response (status=$status, ver=$ver, len=$len, read=". length($response) . ")" : "received zero-sized searchd response"); @@ -1349,7 +1306,7 @@ sub RunQueries { my $nreqs = @{$self->{_reqs}}; my $req = pack("Na*", $nreqs, join("", @{$self->{_reqs}})); $req = pack ( "nnN/a*", SEARCHD_COMMAND_SEARCH, VER_COMMAND_SEARCH, $req); # add header - send($fp, $req ,0); + $fp->write($req); $self->{_reqs} = []; @@ -1578,7 +1535,7 @@ sub BuildExcerpts { ########################## $req = pack ( "nnN/a*", SEARCHD_COMMAND_EXCERPT, VER_COMMAND_EXCERPT, $req); # add header - send($fp, $req ,0); + $fp->write( $req ); my $response = $self->_GetResponse($fp, VER_COMMAND_EXCERPT); return 0 unless ($response);
Subject: Re: [rt.cpan.org #41409] [PATCH] use IO::Socket to improve socket operations
Date: Thu, 04 Dec 2008 18:07:51 +1030
To: bug-Sphinx-Search [...] rt.cpan.org
From: Jon Schutz <Jon.Schutz [...] youramigo.com>
Hi, Thanks for the patch. Apart from being a lot less code, what do you see as the key advantages for using IO::Socket here over basic socket? Regards, -- Jon Schutz My tech notes http://notes.jschutz.net Chief Technology Officer http://www.youramigo.com YourAmigo On Wed, 2008-12-03 at 12:37 -0500, TTY Internet Solutions via RT wrote: Show quoted text
> Wed Dec 03 12:37:37 2008: Request 41409 was acted upon. > Transaction: Ticket created by TTY > Queue: Sphinx-Search > Subject: [PATCH] use IO::Socket to improve socket operations > Broken in: (no value) > Severity: Wishlist > Owner: Nobody > Requestors: cpan@tty.nl > Status: new > Ticket <URL: http://rt.cpan.org/Ticket/Display.html?id=41409 > > > > the patch makes Sphinx::Search use IO::Socket for the socket operations. > > (we couldn't find an email address, so we sent you the patch this way)
On Thu Dec 04 02:38:10 2008, jon.schutz@youramigo.com wrote: Show quoted text
> Hi, > > Thanks for the patch. Apart from being a lot less code, what do you see > as the key advantages for using IO::Socket here over basic socket?
IO::Socket is well tested, and deals correctly with all the status codes of the basic socket operations. (The original code probably didn't handle all the possible status values correctly). IO::Socket is included in the perl CORE, thus it also works everywhere.
Incorporated into current release for Sphinx 0.9.9.