Skip to content

Commit

Permalink
the multi_accept methods do not serve a purpose anymore
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Mar 3, 2016
1 parent 8806096 commit 85504fa
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 79 deletions.
7 changes: 7 additions & 0 deletions Changes
@@ -1,5 +1,12 @@

6.53 2016-03-03
- Removed multi_accept setting from Hypnotoad.
- Removed -M option from daemon and prefork commands.
- Deprecated Mojo::IOLoop::multi_accept.
- Deprecated Mojo::IOLoop::Server::multi_accept.
- Deprecated Mojo::Server::Daemon::multi_accept.
- Added single_accept option to Mojo::IOLoop::Server::listen.
- Added single_accept parameter to Mojo::Server::Daemon::listen.
- Improved performance of many Mojo::Util functions slightly.
- Fixed default value bug in val method of Mojo::DOM.

Expand Down
23 changes: 8 additions & 15 deletions lib/Mojo/IOLoop.pm
Expand Up @@ -9,14 +9,13 @@ use Mojo::IOLoop::Delay;
use Mojo::IOLoop::Server;
use Mojo::IOLoop::Stream;
use Mojo::Reactor::Poll;
use Mojo::Util qw(md5_sum steady_time);
use Mojo::Util qw(deprecated md5_sum steady_time);
use Scalar::Util qw(blessed weaken);

use constant DEBUG => $ENV{MOJO_IOLOOP_DEBUG} || 0;

has max_accepts => 0;
has max_connections => 1000;
has multi_accept => sub { shift->max_connections };
has reactor => sub {
my $class = Mojo::Reactor::Poll->detect;
warn "-- Reactor initialized ($class)\n" if DEBUG;
Expand All @@ -36,8 +35,7 @@ sub acceptor {
return $self->{acceptors}{$acceptor} unless ref $acceptor;

# Connect acceptor with reactor
my $id = $self->_id;
$self->{acceptors}{$id} = $acceptor->multi_accept($self->multi_accept);
$self->{acceptors}{my $id = $self->_id} = $acceptor;
weaken $acceptor->reactor($self->reactor)->{reactor};

# Allow new acceptor to get picked up
Expand Down Expand Up @@ -76,6 +74,12 @@ sub delay {

sub is_running { _instance(shift)->reactor->is_running }

# DEPRECATED in Clinking Beer Mugs!
sub multi_accept {
deprecated 'Mojo::IOLoop::multi_accept is DEPRECATED';
@_ > 1 ? $_[0] : undef;
}

sub next_tick {
my ($self, $cb) = (_instance(shift), @_);
weaken $self;
Expand Down Expand Up @@ -340,17 +344,6 @@ The maximum number of accepted connections this event loop is allowed to handle
concurrently, before stopping to accept new incoming connections, defaults to
C<1000>.
=head2 multi_accept
my $multi = $loop->multi_accept;
$loop = $loop->multi_accept(5);
Number of connections to accept at once, defaults to the value of
L</"max_connections">.
# Accept one connection at a time
$loop->multi_accept(1);
=head2 reactor
my $reactor = $loop->reactor;
Expand Down
29 changes: 18 additions & 11 deletions lib/Mojo/IOLoop/Server.pm
Expand Up @@ -6,6 +6,7 @@ use File::Basename 'dirname';
use File::Spec::Functions 'catfile';
use IO::Socket::IP;
use Mojo::IOLoop;
use Mojo::Util 'deprecated';
use Scalar::Util 'weaken';
use Socket qw(IPPROTO_TCP TCP_NODELAY);

Expand All @@ -21,7 +22,6 @@ use constant TLS_WRITE => TLS ? IO::Socket::SSL::SSL_WANT_WRITE() : 0;
my $CERT = catfile dirname(__FILE__), 'resources', 'server.crt';
my $KEY = catfile dirname(__FILE__), 'resources', 'server.key';

has multi_accept => 50;
has reactor => sub { Mojo::IOLoop->singleton->reactor };

sub DESTROY {
Expand Down Expand Up @@ -78,7 +78,7 @@ sub listen {
$ENV{MOJO_REUSE} .= length $ENV{MOJO_REUSE} ? ",$reuse" : "$reuse";
}
$handle->blocking(0);
$self->{handle} = $handle;
@$self{qw(handle single_accept)} = ($handle, $args->{single_accept});

return unless $args->{tls};
croak "IO::Socket::SSL 1.94+ required for TLS support" unless TLS;
Expand All @@ -102,6 +102,12 @@ sub listen {
$tls->{SSL_version} = $args->{tls_version} if $args->{tls_version};
}

# DEPRECATED in Clinking Beer Mugs!
sub multi_accept {
deprecated 'Mojo::IOLoop::Server::multi_accept is DEPRECATED';
@_ > 1 ? $_[0] : undef;
}

sub port { shift->{handle}->sockport }

sub start {
Expand All @@ -117,8 +123,10 @@ sub _accept {
my $self = shift;

# Greedy accept
for (1 .. $self->multi_accept) {
return unless $self->{active} && (my $handle = $self->{handle}->accept);
my $accepted = 0;
while (1) {
return if !$self->{active} || ($accepted++ && $self->{single_accept});
return unless my $handle = $self->{handle}->accept;
$handle->blocking(0);

# Disable Nagle's algorithm
Expand Down Expand Up @@ -201,13 +209,6 @@ Emitted for each accepted connection.
L<Mojo::IOLoop::Server> implements the following attributes.
=head2 multi_accept
my $multi = $server->multi_accept;
$server = $server->multi_accept(100);
Number of connections to accept at once, defaults to C<50>.
=head2 reactor
my $reactor = $server->reactor;
Expand Down Expand Up @@ -275,6 +276,12 @@ Port to listen on, defaults to a random port.
Allow multiple servers to use the same port with the C<SO_REUSEPORT> socket
option.
=item single_accept
single_accept => 1
Only accept one connection at a time.
=item tls
tls => 1
Expand Down
32 changes: 18 additions & 14 deletions lib/Mojo/Server/Daemon.pm
Expand Up @@ -5,14 +5,14 @@ use Carp 'croak';
use Mojo::IOLoop;
use Mojo::Transaction::WebSocket;
use Mojo::URL;
use Mojo::Util 'term_escape';
use Mojo::Util qw(deprecated term_escape);
use Mojo::WebSocket 'server_handshake';
use Scalar::Util 'weaken';

use constant DEBUG => $ENV{MOJO_DAEMON_DEBUG} || 0;

has acceptors => sub { [] };
has [qw(backlog max_clients multi_accept silent)];
has [qw(backlog max_clients silent)];
has inactivity_timeout => sub { $ENV{MOJO_INACTIVITY_TIMEOUT} // 15 };
has ioloop => sub { Mojo::IOLoop->singleton };
has listen => sub { [split ',', $ENV{MOJO_LISTEN} || 'http://*:3000'] };
Expand All @@ -26,6 +26,12 @@ sub DESTROY {
$loop->remove($_) for @{$self->acceptors};
}

# DEPRECATED in Clinking Beer Mugs!
sub multi_accept {
deprecated 'Mojo::Server::Daemon::multi_accept is DEPRECATED';
@_ > 1 ? $_[0] : undef;
}

sub run {
my $self = shift;

Expand All @@ -43,7 +49,6 @@ sub start {
# Resume accepting connections
my $loop = $self->ioloop;
if (my $max = $self->max_clients) { $loop->max_connections($max) }
if (defined(my $multi = $self->multi_accept)) { $loop->multi_accept($multi) }
if (my $servers = $self->{servers}) {
push @{$self->acceptors}, $loop->acceptor(delete $servers->{$_})
for keys %$servers;
Expand Down Expand Up @@ -163,9 +168,10 @@ sub _listen {

my $query = $url->query;
my $options = {
address => $url->host,
backlog => $self->backlog,
reuse => $query->param('reuse')
address => $url->host,
backlog => $self->backlog,
single_accept => $query->param('single_accept'),
reuse => $query->param('reuse')
};
if (my $port = $url->port) { $options->{port} = $port }
$options->{"tls_$_"} = $query->param($_) for qw(ca ciphers version);
Expand Down Expand Up @@ -409,6 +415,12 @@ Path to the TLS key file, defaults to a built-in test key.
Allow multiple servers to use the same port with the C<SO_REUSEPORT> socket
option.
=item single_accept
single_accept=1
Only accept one connection at a time.
=item verify
verify=0x00
Expand Down Expand Up @@ -439,14 +451,6 @@ to L<Mojo::IOLoop/"max_connections">.
Maximum number of keep-alive requests per connection, defaults to C<25>.
=head2 multi_accept
my $multi = $daemon->multi_accept;
$daemon = $daemon->multi_accept(5);
Number of connections to accept at once, passed along to
L<Mojo::IOLoop/"multi_accept">.
=head2 silent
my $bool = $daemon->silent;
Expand Down
9 changes: 1 addition & 8 deletions lib/Mojo/Server/Hypnotoad.pm
Expand Up @@ -27,8 +27,7 @@ sub configure {
$prefork->max_requests($c->{requests}) if $c->{requests};
defined $c->{$_} and $prefork->$_($c->{$_})
for qw(accepts backlog graceful_timeout heartbeat_interval),
qw(heartbeat_timeout inactivity_timeout listen multi_accept pid_file),
qw(workers);
qw(heartbeat_timeout inactivity_timeout listen pid_file workers);
}

sub run {
Expand Down Expand Up @@ -301,12 +300,6 @@ Setting the value to C<0> will allow connections to be inactive indefinitely.
Array reference with one or more locations to listen on, defaults to
C<http://*:8080>. See also L<Mojo::Server::Daemon/"listen"> for more examples.
=head2 multi_accept
multi_accept => 5
Number of connections to accept at once, defaults to the value of L</"clients">.
=head2 pid_file
pid_file => '/var/run/hypnotoad.pid'
Expand Down
10 changes: 3 additions & 7 deletions lib/Mojolicious/Command/daemon.pm
Expand Up @@ -15,10 +15,9 @@ sub run {
'b|backlog=i' => sub { $daemon->backlog($_[1]) },
'c|clients=i' => sub { $daemon->max_clients($_[1]) },
'i|inactivity-timeout=i' => sub { $daemon->inactivity_timeout($_[1]) },
'l|listen=s' => \my @listen,
'M|multi-accept=i' => sub { $daemon->multi_accept($_[1]) },
'p|proxy' => sub { $daemon->reverse_proxy(1) },
'r|requests=i' => sub { $daemon->max_requests($_[1]) };
'l|listen=s' => \my @listen,
'p|proxy' => sub { $daemon->reverse_proxy(1) },
'r|requests=i' => sub { $daemon->max_requests($_[1]) };

$daemon->listen(\@listen) if @listen;
$daemon->run;
Expand Down Expand Up @@ -55,9 +54,6 @@ Mojolicious::Command::daemon - Daemon command
-l, --listen <location> One or more locations you want to
listen on, defaults to the value of
MOJO_LISTEN or "http://*:3000"
-M, --multi-accept <number> Number of connections to accept at
once, defaults to the value of
--clients
-m, --mode <name> Operating mode for your application,
defaults to the value of
MOJO_MODE/PLACK_ENV or "development"
Expand Down
14 changes: 5 additions & 9 deletions lib/Mojolicious/Command/prefork.pm
Expand Up @@ -20,12 +20,11 @@ sub run {
'I|heartbeat-interval=i' => sub { $prefork->heartbeat_interval($_[1]) },
'H|heartbeat-timeout=i' => sub { $prefork->heartbeat_timeout($_[1]) },
'i|inactivity-timeout=i' => sub { $prefork->inactivity_timeout($_[1]) },
'l|listen=s' => \my @listen,
'M|multi-accept=i' => sub { $prefork->multi_accept($_[1]) },
'P|pid-file=s' => sub { $prefork->pid_file($_[1]) },
'p|proxy' => sub { $prefork->reverse_proxy(1) },
'r|requests=i' => sub { $prefork->max_requests($_[1]) },
'w|workers=i' => sub { $prefork->workers($_[1]) };
'l|listen=s' => \my @listen,
'P|pid-file=s' => sub { $prefork->pid_file($_[1]) },
'p|proxy' => sub { $prefork->reverse_proxy(1) },
'r|requests=i' => sub { $prefork->max_requests($_[1]) },
'w|workers=i' => sub { $prefork->workers($_[1]) };

$prefork->listen(\@listen) if @listen;
$prefork->run;
Expand Down Expand Up @@ -67,9 +66,6 @@ Mojolicious::Command::prefork - Prefork command
-l, --listen <location> One or more locations you want to
listen on, defaults to the value of
MOJO_LISTEN or "http://*:3000"
-M, --multi-accept <number> Number of connections to accept at
once, defaults to the value of
--clients
-m, --mode <name> Operating mode for your application,
defaults to the value of
MOJO_MODE/PLACK_ENV or "development"
Expand Down
64 changes: 58 additions & 6 deletions t/mojo/daemon.t
Expand Up @@ -261,16 +261,14 @@ like $buffer, qr/Mojo$/, 'transactions were pipelined';

# Throttling
$daemon = Mojo::Server::Daemon->new(
app => $app,
listen => ['http://127.0.0.1'],
max_clients => 23,
multi_accept => 3,
silent => 1
app => $app,
listen => ['http://127.0.0.1'],
max_clients => 23,
silent => 1
);
is scalar @{$daemon->acceptors}, 0, 'no active acceptors';
is scalar @{$daemon->start->start->acceptors}, 1, 'one active acceptor';
is $daemon->ioloop->max_connections, 23, 'right value';
is $daemon->ioloop->multi_accept, 3, 'right value';
$id = $daemon->acceptors->[0];
ok !!Mojo::IOLoop->acceptor($id), 'acceptor has been added';
is scalar @{$daemon->stop->acceptors}, 0, 'no active acceptors';
Expand All @@ -281,6 +279,60 @@ ok !!Mojo::IOLoop->acceptor($id), 'acceptor has been added';
undef $daemon;
ok !Mojo::IOLoop->acceptor($id), 'acceptor has been removed';

# Single-accept and connection limit
my $loop = Mojo::IOLoop->new;
$daemon = Mojo::Server::Daemon->new(
app => $app,
ioloop => $loop,
listen => ['http://127.0.0.1?single_accept=1'],
max_clients => 2,
silent => 1
)->start;
my $acceptor = $loop->acceptor($daemon->acceptors->[0]);
my @accepting;
$acceptor->on(
accept => sub {
my $acceptor = shift;
$loop->next_tick(
sub {
push @accepting, $acceptor->is_accepting;
shift->stop if @accepting == 2;
}
);
}
);
$loop->client({port => $acceptor->port} => sub { }) for 1 .. 2;
$loop->start;
ok $accepting[0], 'accepting connections';
ok !$accepting[1], 'connection limit reached';

# Multi-accept
$loop = Mojo::IOLoop->new;
$daemon = Mojo::Server::Daemon->new(
app => $app,
ioloop => $loop,
listen => ['http://127.0.0.1'],
max_clients => 2,
silent => 1
)->start;
$acceptor = $loop->acceptor($daemon->acceptors->[0]);
@accepting = ();
$acceptor->on(
accept => sub {
my $acceptor = shift;
$loop->next_tick(
sub {
push @accepting, $acceptor->is_accepting;
shift->stop if @accepting == 2;
}
);
}
);
$loop->client({port => $acceptor->port} => sub { }) for 1 .. 2;
$loop->start;
ok !$accepting[0], 'connection limit reached';
ok !$accepting[1], 'connection limit reached';

# Abstract methods
eval { Mojo::Server->run };
like $@, qr/Method "run" not implemented by subclass/, 'right error';
Expand Down

0 comments on commit 85504fa

Please sign in to comment.