[PATCH 1 of 5 hgweb-thread-isolation] hgweb: add some documentation

Gregory Szorc gregory.szorc at gmail.com
Tue Sep 1 19:11:07 UTC 2015


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1440277139 25200
#      Sat Aug 22 13:58:59 2015 -0700
# Node ID eea0ca94b0f571f117b62f4e7ebcc593fcf0bf73
# Parent  049005de325ea400893f45bd6221215cc9b26db0
hgweb: add some documentation

It took longer than I wanted to grok how the various parts of hgweb
worked. So I added some class and method documentation to help whoever
hacks on this next.

diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -61,8 +61,18 @@ def makebreadcrumb(url, prefix=''):
     return reversed(breadcrumb)
 
 
 class hgweb(object):
+    """HTTP server for individual repositories.
+
+    Instances of this class serve HTTP responses for a particular
+    repository.
+
+    Instances are typically used as WSGI applications.
+
+    Some servers are multi-threaded. On these servers, there may
+    be multiple active threads inside __call__.
+    """
     def __init__(self, repo, name=None, baseui=None):
         if isinstance(repo, str):
             if baseui:
                 u = baseui.copy()
@@ -156,20 +166,33 @@ class hgweb(object):
         if request:
             self.repo.ui.environ = request.env
 
     def run(self):
+        """Start a server from CGI environment.
+
+        Modern servers should be using WSGI and should avoid this
+        method, if possible.
+        """
         if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
             raise RuntimeError("This function is only intended to be "
                                "called while running as a CGI script.")
         import mercurial.hgweb.wsgicgi as wsgicgi
         wsgicgi.launch(self)
 
     def __call__(self, env, respond):
+        """Run the WSGI application.
+
+        This may be called by multiple threads.
+        """
         req = wsgirequest(env, respond)
         return self.run_wsgi(req)
 
     def run_wsgi(self, req):
+        """Internal method to run the WSGI application.
 
+        This is typically only called by Mercurial. External consumers
+        should be using instances of this class as the WSGI application.
+        """
         self.refresh(req)
 
         # work with CGI variables to create coherent structure
         # use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME
diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -78,8 +78,15 @@ def geturlcgivars(baseurl, port):
 
     return name, str(port), path
 
 class hgwebdir(object):
+    """HTTP server for multiple repositories.
+
+    Given a configuration, different repositories will be served depending
+    on the request path.
+
+    Instances are typically used as WSGI applications.
+    """
     def __init__(self, conf, baseui=None):
         self.conf = conf
         self.baseui = baseui
         self.ui = None
diff --git a/mercurial/hgweb/request.py b/mercurial/hgweb/request.py
--- a/mercurial/hgweb/request.py
+++ b/mercurial/hgweb/request.py
@@ -39,8 +39,14 @@ def normalize(form):
         form[k] = [i.strip() for i in v]
     return form
 
 class wsgirequest(object):
+    """Higher-level API for a WSGI request.
+
+    WSGI applications are invoked with 2 arguments. They are used to
+    instantiate instances of this class, which provides higher-level APIs
+    for obtaining request parameters, writing HTTP output, etc.
+    """
     def __init__(self, wsgienv, start_response):
         version = wsgienv['wsgi.version']
         if (version < (1, 0)) or (version >= (2, 0)):
             raise RuntimeError("Unknown and unsupported WSGI version %d.%d"


More information about the Mercurial-devel mailing list