Allow size of reads from socket to be tuned
[perl-Redis.git] / lib / Redis.pm
index 346b995..ef4e53c 100644 (file)
@@ -4,6 +4,7 @@ use warnings;
 use strict;
 
 use IO::Socket::INET;
+use Fcntl qw( O_NONBLOCK F_SETFL );
 use Data::Dumper;
 use Carp qw/confess/;
 use Encode;
@@ -53,7 +54,9 @@ sub new {
     PeerAddr => $self->{server},
     Proto    => 'tcp',
   ) || confess("Could not connect to Redis server at $self->{server}: $!");
-  $self->{rbuf} = '';
+
+  $self->{read_size} = 8192;
+  $self->{rbuf}      = '';
 
   $self->{is_subscriber} = 0;
 
@@ -127,7 +130,7 @@ sub __is_valid_command {
   my ($self, $cmd) = @_;
 
   return unless $self->{is_subscriber};
-  return if $cmd =~ /^P?(UN)?SUBSCRIBE$/;
+  return if $cmd =~ /^P?(UN)?SUBSCRIBE$/i;
   confess("Cannot use command '$cmd' while in SUBSCRIBE mode, ");
 }
 
@@ -201,7 +204,9 @@ sub __read_sock {
   my $rbuf = \($self->{rbuf});
 
   my ($data, $type) = ('', '');
-  my $read_size = defined $len ? $len + 2 : 8192;
+  my $read_size = $self->{read_size};
+  $read_size = $len + 2 if defined $len && $len + 2 > $read_size;
+
   while (1) {
     ## Read NN bytes, strip \r\n at the end
     if (defined $len) {
@@ -229,6 +234,27 @@ sub __read_sock {
   return $data;
 }
 
+sub __can_read_sock {
+  my ($self) = @_;
+  my $sock   = $self->{sock};
+  my $rbuf   = \($self->{rbuf});
+
+  return 1 if $$rbuf;
+  __fh_nonblocking($sock, 1);
+  my $bytes = sysread $sock, $$rbuf, $self->{read_size}, length $$rbuf;
+  __fh_nonblocking($sock, 0);
+  return 1 if $bytes;
+  return 0;
+}
+
+
+### Copied from AnyEvent::Util
+BEGIN {
+  *__fh_nonblocking = ($^O eq 'MSWin32')
+    ? sub($$) { ioctl $_[0], 0x8004667e, pack "L", $_[1]; }    # FIONBIO
+    : sub($$) { fcntl $_[0], F_SETFL, $_[1] ? O_NONBLOCK : 0; };
+}
+
 
 1;