diff options
author | Eric Wong <e@80x24.org> | 2016-07-09 03:18:34 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2016-07-09 03:20:24 +0000 |
commit | f89bd1444a595b569606679293d2d01b0b7a049e (patch) | |
tree | fbb8007c319f0655adbc1245dfff48bd441c720f /lib/PublicInbox/Qspawn.pm | |
parent | 239514fd687eb88d023b67de1daccaf2e440e884 (diff) | |
download | public-inbox-f89bd1444a595b569606679293d2d01b0b7a049e.tar.gz |
And bump the default limit to 32 so we match git-daemon behavior. This shall allow us to configure different levels of concurrency for different repositories and prevent clones of giant repos from stalling service to small repos.
Diffstat (limited to 'lib/PublicInbox/Qspawn.pm')
-rw-r--r-- | lib/PublicInbox/Qspawn.pm | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/lib/PublicInbox/Qspawn.pm b/lib/PublicInbox/Qspawn.pm index 9299096a..cc9c340d 100644 --- a/lib/PublicInbox/Qspawn.pm +++ b/lib/PublicInbox/Qspawn.pm @@ -1,12 +1,14 @@ # Copyright (C) 2016 all contributors <meta@public-inbox.org> # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt> + +# Limits the number of processes spawned +# This does not depend on Danga::Socket or any other external +# scheduling mechanism, you just need to call start and finish +# appropriately package PublicInbox::Qspawn; use strict; use warnings; use PublicInbox::Spawn qw(popen_rd); -our $LIMIT = 1; -my $running = 0; -my @run_queue; sub new ($$$;) { my ($class, $cmd, $env, $opt) = @_; @@ -16,9 +18,10 @@ sub new ($$$;) { sub _do_spawn { my ($self, $cb) = @_; my $err; + ($self->{rpipe}, $self->{pid}) = popen_rd(@{$self->{args}}); if (defined $self->{pid}) { - $running++; + $self->{limiter}->{running}++; } else { $self->{err} = $!; } @@ -27,26 +30,41 @@ sub _do_spawn { sub finish ($) { my ($self) = @_; + my $limiter = $self->{limiter}; if (delete $self->{rpipe}) { my $pid = delete $self->{pid}; $self->{err} = $pid == waitpid($pid, 0) ? $? : "PID:$pid still running?"; - $running--; + $limiter->{running}--; } - if (my $next = shift @run_queue) { + if (my $next = shift @{$limiter->{run_queue}}) { _do_spawn(@$next); } $self->{err}; } -sub start ($$) { - my ($self, $cb) = @_; +sub start { + my ($self, $limiter, $cb) = @_; + $self->{limiter} = $limiter; - if ($running < $LIMIT) { + if ($limiter->{running} < $limiter->{limit}) { _do_spawn($self, $cb); } else { - push @run_queue, [ $self, $cb ]; + push @{$limiter->{run_queue}}, [ $self, $cb ]; } } +package PublicInbox::Qspawn::Limiter; +use strict; +use warnings; + +sub new { + my ($class, $limit) = @_; + bless { + limit => $limit || 1, + running => 0, + run_queue => [], + }, $class; +} + 1; |