D2461: wireprotoserver: ability to run an SSH server until an event is set

indygreg (Gregory Szorc) phabricator at mercurial-scm.org
Mon Feb 26 21:16:42 UTC 2018


indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  It seems useful to be able to start an SSH protocol server that
  won't run forever and won't call sys.exit() when it stops. This
  could be used to facilitate intra-process testing of the SSH
  protocol, for example.
  
  We teach the server function to loop until a threading.Event is set
  and invent a new API to run the server until an event is set. It also
  won't sys.exit() afterwards.
  
  There aren't many callers of serve_forever(). So we could refactor
  them relatively easily. But I was lazy.
  
  threading.Event might be a bit heavyweight. An alternative would be
  a list whose only elements is changed. We can't use a simple scalar
  value like a bool or int because those types are immutable. Events
  are what you use in systems programming for this use case, so the
  use of threading.Event seems justified.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2461

AFFECTED FILES
  mercurial/wireprotoserver.py

CHANGE DETAILS

diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py
--- a/mercurial/wireprotoserver.py
+++ b/mercurial/wireprotoserver.py
@@ -9,6 +9,7 @@
 import contextlib
 import struct
 import sys
+import threading
 
 from .i18n import _
 from . import (
@@ -373,7 +374,7 @@
 class sshv2protocolhandler(sshv1protocolhandler):
     """Protocol handler for version 2 of the SSH protocol."""
 
-def _runsshserver(ui, repo, fin, fout):
+def _runsshserver(ui, repo, fin, fout, ev):
     # This function operates like a state machine of sorts. The following
     # states are defined:
     #
@@ -430,7 +431,7 @@
     proto = sshv1protocolhandler(ui, fin, fout)
     protoswitched = False
 
-    while True:
+    while not ev.is_set():
         if state == 'protov1-serving':
             # Commands are issued on new lines.
             request = fin.readline()[:-1]
@@ -601,5 +602,9 @@
         util.setbinary(self._fout)
 
     def serve_forever(self):
-        _runsshserver(self._ui, self._repo, self._fin, self._fout)
+        self.serveuntil(threading.Event())
         sys.exit(0)
+
+    def serveuntil(self, ev):
+        """Serve until a threading.Event is set."""
+        _runsshserver(self._ui, self._repo, self._fin, self._fout, ev)



To: indygreg, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list