about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2023-10-31 20:42:52 +0000
committerEric Wong <e@80x24.org>2023-11-01 07:08:09 +0000
commitfdf90c0ffbf608ed08665eaffa5c750fa5a5bfee (patch)
treef9365a4472ef6e5dda901c68cc7c36b7da8c9fff /lib
parent4d2f3651bde2f2c61b78973df56b6e6ee37a6dce (diff)
downloadpublic-inbox-fdf90c0ffbf608ed08665eaffa5c750fa5a5bfee.tar.gz
The epoll implementation is the only one which respects the
limit (kevent would, but IO::KQueue does not).  In any case,
I'm not a fan of the maxevents=1000 historical default since
it leads to fairness problems with shared non-blocking listeners
across multiple daemon workers.
Diffstat (limited to 'lib')
-rw-r--r--lib/PublicInbox/DS.pm4
-rw-r--r--lib/PublicInbox/DSKQXS.pm3
-rw-r--r--lib/PublicInbox/DSPoll.pm2
-rw-r--r--lib/PublicInbox/Epoll.pm5
-rw-r--r--lib/PublicInbox/Select.pm2
5 files changed, 10 insertions, 6 deletions
diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm
index b30e9db6..9e1f66c2 100644
--- a/lib/PublicInbox/DS.pm
+++ b/lib/PublicInbox/DS.pm
@@ -287,8 +287,8 @@ sub event_loop (;$$) {
         do {
                 my $timeout = RunTimers();
 
-                # get up to 1000 FDs representing events
-                $Poller->ep_wait(1000, $timeout, \@active);
+                # grab whatever FDs are ready
+                $Poller->ep_wait($timeout, \@active);
 
                 # map all FDs to their associated Perl object
                 @active = @DescriptorMap{@active};
diff --git a/lib/PublicInbox/DSKQXS.pm b/lib/PublicInbox/DSKQXS.pm
index 8ef8ffb6..f84c196a 100644
--- a/lib/PublicInbox/DSKQXS.pm
+++ b/lib/PublicInbox/DSKQXS.pm
@@ -117,7 +117,8 @@ sub ep_del {
 }
 
 sub ep_wait {
-        my ($self, $maxevents, $timeout_msec, $events) = @_;
+        my ($self, $timeout_msec, $events) = @_;
+        # n.b.: IO::KQueue is hard-coded to return up to 1000 events
         @$events = eval { $self->{kq}->kevent($timeout_msec) };
         if (my $err = $@) {
                 # workaround https://rt.cpan.org/Ticket/Display.html?id=116615
diff --git a/lib/PublicInbox/DSPoll.pm b/lib/PublicInbox/DSPoll.pm
index 0446df4c..b947f756 100644
--- a/lib/PublicInbox/DSPoll.pm
+++ b/lib/PublicInbox/DSPoll.pm
@@ -18,7 +18,7 @@ use Errno ();
 sub new { bless {}, __PACKAGE__ } # fd => events
 
 sub ep_wait {
-        my ($self, $maxevents, $timeout_msec, $events) = @_;
+        my ($self, $timeout_msec, $events) = @_;
         my (@pset, $n, $fd, $revents, $nval);
         while (my ($fd, $events) = each %$self) {
                 my $pevents = $events & EPOLLIN ? POLLIN : 0;
diff --git a/lib/PublicInbox/Epoll.pm b/lib/PublicInbox/Epoll.pm
index d55c8535..7e0aa6e7 100644
--- a/lib/PublicInbox/Epoll.pm
+++ b/lib/PublicInbox/Epoll.pm
@@ -18,6 +18,9 @@ sub new {
 sub ep_add { epoll_ctl(fileno(${$_[0]}), EPOLL_CTL_ADD, fileno($_[1]), $_[2]) }
 sub ep_mod { epoll_ctl(fileno(${$_[0]}), EPOLL_CTL_MOD, fileno($_[1]), $_[2]) }
 sub ep_del { epoll_ctl(fileno(${$_[0]}), EPOLL_CTL_DEL, fileno($_[1]), 0) }
-sub ep_wait { epoll_wait(fileno(${$_[0]}), @_[1, 2, 3]) }
+
+# n.b. maxevents=1000 is the historical default.  maxevents=1 (yes, one)
+# is more fair under load with multiple worker processes sharing one listener
+sub ep_wait { epoll_wait(fileno(${$_[0]}), 1000, @_[1, 2]) }
 
 1;
diff --git a/lib/PublicInbox/Select.pm b/lib/PublicInbox/Select.pm
index 5817c9ef..5cb7aff3 100644
--- a/lib/PublicInbox/Select.pm
+++ b/lib/PublicInbox/Select.pm
@@ -12,7 +12,7 @@ use PublicInbox::Syscall qw(EPOLLONESHOT EPOLLIN EPOLLOUT);
 sub new { bless {}, __PACKAGE__ } # fd => events
 
 sub ep_wait {
-        my ($self, $maxevents, $msec, $events) = @_;
+        my ($self, $msec, $events) = @_;
         my ($rvec, $wvec) = ('', ''); # we don't use EPOLLERR
         while (my ($fd, $ev) = each %$self) {
                 vec($rvec, $fd, 1) = 1 if $ev & EPOLLIN;