Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Nov 2013 19:11:55 +0000 (UTC)
From:      Mikolaj Golub <trociny@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r334606 - in head/sysutils/p5-MogileFS-Server: . files
Message-ID:  <201311221911.rAMJBts4013000@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trociny
Date: Fri Nov 22 19:11:55 2013
New Revision: 334606
URL: http://svnweb.freebsd.org/changeset/ports/334606

Log:
  Fix a regression introduce in 2.70 when the mogilefs server was
  rewritten to be non-blocking: immediate write after connect may fail
  if the connection is not ready yet.
  
  Approved by:	bdrewery (mentor)

Added:
  head/sysutils/p5-MogileFS-Server/files/patch-Poolable.pm   (contents, props changed)
Modified:
  head/sysutils/p5-MogileFS-Server/Makefile

Modified: head/sysutils/p5-MogileFS-Server/Makefile
==============================================================================
--- head/sysutils/p5-MogileFS-Server/Makefile	Fri Nov 22 19:07:32 2013	(r334605)
+++ head/sysutils/p5-MogileFS-Server/Makefile	Fri Nov 22 19:11:55 2013	(r334606)
@@ -3,6 +3,7 @@
 
 PORTNAME=	MogileFS-Server
 PORTVERSION=	2.70
+PORTREVISION=	1
 CATEGORIES=	sysutils perl5
 MASTER_SITES=	CPAN
 MASTER_SITE_SUBDIR=	CPAN:DORMANDO

Added: head/sysutils/p5-MogileFS-Server/files/patch-Poolable.pm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sysutils/p5-MogileFS-Server/files/patch-Poolable.pm	Fri Nov 22 19:11:55 2013	(r334606)
@@ -0,0 +1,73 @@
+Eric Wong: connection/poolable: do not write before event_write
+
+Blindly attempting to write to a socket before a TCP connection can be
+established returns EAGAIN on Linux, but not on FreeBSD 8/9.  This
+causes Danga::Socket to error out, as it won't attempt to buffer on
+anything but EAGAIN on write() attempts.
+
+Now, we buffer writes explicitly after the initial socket creation and
+connect(), and only call Danga::Socket::write when we've established
+writability.  This works on Linux, too, and avoids an unnecessary
+syscall in most cases.
+
+Reported-by: Alex Yakovenko <aleksey.yakovenko@gmail.com>
+
+--- lib/MogileFS/Connection/Poolable.pm.orig	2013-08-19 05:52:33.000000000 +0300
++++ lib/MogileFS/Connection/Poolable.pm	2013-11-20 22:57:31.000000000 +0200
+@@ -13,6 +13,7 @@ use fields (
+     'mfs_expire_cb',  # Danga::Socket::Timer callback
+     'mfs_requests',   # number of requests made on this object
+     'mfs_err',        # used to propagate an error to start()
++    'mfs_writeq',     # arrayref if connecting, undef otherwise
+ );
+ use Socket qw(SO_KEEPALIVE);
+ use Time::HiRes;
+@@ -27,6 +28,9 @@ sub new {
+     $self->{mfs_hostport} = [ $ip, $port ];
+     $self->{mfs_requests} = 0;
+ 
++    # newly-created socket, we buffer writes until event_write is triggered
++    $self->{mfs_writeq} = [];
++
+     return $self;
+ }
+ 
+@@ -53,6 +57,38 @@ sub mark_idle {
+     $self->{mfs_requests}++;
+ }
+ 
++sub write {
++    my ($self, $arg) = @_;
++    my $writeq = $self->{mfs_writeq};
++
++    if (ref($writeq) eq "ARRAY") {
++        # if we're still connecting, we must buffer explicitly for *BSD
++        # and not attempt a real write() until event_write is triggered
++        push @$writeq, $arg;
++        $self->watch_write(1); # enable event_write triggering
++        0; # match Danga::Socket::write return value
++    } else {
++        $self->SUPER::write($arg);
++    }
++}
++
++# Danga::Socket will trigger this when a socket is writable
++sub event_write {
++    my ($self) = @_;
++
++    # we may have buffered writes in mfs_writeq during non-blocking connect(),
++    # this is needed on *BSD but unnecessary (but harmless) on Linux.
++    my $writeq = delete $self->{mfs_writeq};
++    if ($writeq) {
++        $self->watch_write(0); # ->write will re-enable if needed
++        foreach my $queued (@$writeq) {
++            $self->write($queued);
++        }
++    } else {
++        $self->SUPER::event_write();
++    }
++}
++
+ # the request running on this connection is retryable if this socket
+ # has ever been marked idle.  The connection pool can never be 100%
+ # reliable for detecting dead sockets, and all HTTP requests made by



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201311221911.rAMJBts4013000>