commandserver: use selectors2
authorJun Wu <quark@fb.com>
Fri, 14 Jul 2017 20:26:21 -0700
changeset 33503 27d23fe32887
parent 33502 5d0c0c8d2929
child 33504 5d3ba4395288
commandserver: use selectors2 Previously, commandserver was using select.select. That could have issue if _sock.fileno() >= FD_SETSIZE (usually 1024), which raises: ValueError: filedescriptor out of range in select() We got that in production today, although it's the code opening that many files to blame, it seems better for commandserver to work in this case. There are multiple way to "solve" it, like preserving a fd with a small number and swap it with sock using dup2(). But upgrading to a modern selector supported by the system seems to be the most correct way.
mercurial/commandserver.py
--- a/mercurial/commandserver.py	Fri Jul 14 20:19:46 2017 -0700
+++ b/mercurial/commandserver.py	Fri Jul 14 20:26:21 2017 -0700
@@ -22,6 +22,7 @@
     encoding,
     error,
     pycompat,
+    selectors2,
     util,
 )
 
@@ -476,6 +477,8 @@
     def _mainloop(self):
         exiting = False
         h = self._servicehandler
+        selector = selectors2.DefaultSelector()
+        selector.register(self._sock, selectors2.EVENT_READ)
         while True:
             if not exiting and h.shouldexit():
                 # clients can no longer connect() to the domain socket, so
@@ -486,7 +489,7 @@
                 self._unlinksocket()
                 exiting = True
             try:
-                ready = select.select([self._sock], [], [], h.pollinterval)[0]
+                ready = selector.select(timeout=h.pollinterval)
                 if not ready:
                     # only exit if we completed all queued requests
                     if exiting: