# HG changeset patch # User Ludovic Chabant # Date 1412885128 25200 # Node ID 01221c791547e3cb7b586990cdba720bf2db3a2b # Parent 61902f36c789f153180588c4a946d0f1be972e80 Only connect to the Mercurial command server when needed. Remove (probably?) unnecessary locking. diff -r 61902f36c789 -r 01221c791547 wikked/scm/mercurial.py --- a/wikked/scm/mercurial.py Wed Oct 08 23:27:00 2014 -0700 +++ b/wikked/scm/mercurial.py Thu Oct 09 13:05:28 2014 -0700 @@ -190,56 +190,58 @@ cl_lock = threading.Lock() +def create_hg_client(root): + logger.debug("Spawning Mercurial command server at: %s" % root) + import hglib + global hg_client + hg_client = hglib.open(root) + + def shutdown_commandserver(num, frame): + global hg_client + if hg_client is not None: + with cl_lock: + if hg_client is not None: + logger.debug("Shutting down Mercurial command server.") + hg_client.close() + hg_client = None + import atexit + atexit.register(shutdown_commandserver, None, None) + try: + import signal + signal.signal(signal.SIGTERM, shutdown_commandserver) + except: + # `mod_wsgi` prevents adding stuff to `SIGTERM` + # so let's not make a big deal if this doesn't + # go through. + pass + + class MercurialCommandServerSourceControl(MercurialBaseSourceControl): def __init__(self, root, client=None): MercurialBaseSourceControl.__init__(self, root) - self.client = client + self._client = client def _initRepo(self, root): exe = ['hg', 'init', root] logger.debug("Running Mercurial: " + str(exe)) return subprocess.check_output(exe) - def _doStart(self): - if self.client is None: + @property + def client(self): + if self._client is None: if hg_client is None: with cl_lock: if hg_client is None: - self._createServer() - self.client = hg_client + create_hg_client(self.root) + self._client = hg_client else: logger.debug("Re-using existing Mercurial command server.") - self.client = hg_client - - def _createServer(self): - logger.debug("Spawning Mercurial command server.") - import hglib - global hg_client - hg_client = hglib.open(self.root) - - def shutdown_commandserver(num, frame): - global hg_client - if hg_client is not None: - with cl_lock: - if hg_client is not None: - logger.debug("Shutting down Mercurial command server.") - hg_client.close() - hg_client = None - import atexit - atexit.register(shutdown_commandserver, None, None) - try: - import signal - signal.signal(signal.SIGTERM, shutdown_commandserver) - except: - # `mod_wsgi` prevents adding stuff to `SIGTERM` - # so let's not make a big deal if this doesn't - # go through. - pass + self._client = hg_client + return self._client def getHistory(self, path=None, limit=10, after_rev=None): if path is not None: - with cl_lock: - status = self.client.status(include=[path]) + status = self.client.status(include=[path]) if len(status) > 0 and status[0] == '?': return [] @@ -251,14 +253,12 @@ needs_files = False if path is not None: - with cl_lock: - repo_revs = self.client.log(files=[path], follow=True, - limit=limit, revrange=rev) + repo_revs = self.client.log(files=[path], follow=True, + limit=limit, revrange=rev) else: needs_files = True - with cl_lock: - repo_revs = self.client.log(follow=True, limit=limit, - revrange=rev) + repo_revs = self.client.log(follow=True, limit=limit, + revrange=rev) revisions = [] for rev in repo_revs: r = Revision(rev.node) @@ -267,8 +267,7 @@ r.timestamp = time.mktime(rev.date.timetuple()) r.description = unicode(rev.desc) if needs_files: - with cl_lock: - rev_statuses = self.client.status(change=rev.node) + rev_statuses = self.client.status(change=rev.node) for rev_status in rev_statuses: r.files.append({ 'path': rev_status[1].decode('utf-8', 'replace'), @@ -278,8 +277,7 @@ return revisions def getState(self, path): - with cl_lock: - statuses = self.client.status(include=[path]) + statuses = self.client.status(include=[path]) if len(statuses) == 0: return STATE_COMMITTED status = statuses[0] @@ -290,14 +288,12 @@ raise Exception("Unsupported status: %s" % status) def getRevision(self, path, rev): - with cl_lock: - return self.client.cat([path], rev=rev) + return self.client.cat([path], rev=rev) def diff(self, path, rev1, rev2): - with cl_lock: - if rev2 is None: - return self.client.diff(files=[path], change=rev1, git=True) - return self.client.diff(files=[path], revs=[rev1, rev2], git=True) + if rev2 is None: + return self.client.diff(files=[path], change=rev1, git=True) + return self.client.diff(files=[path], revs=[rev1, rev2], git=True) def commit(self, paths, op_meta): if 'message' not in op_meta or not op_meta['message']: @@ -313,15 +309,13 @@ args = cmdbuilder('commit', *paths, debug=True, m=op_meta['message'], A=True, **kwargs) - with cl_lock: - self.client.rawcommand(args) + self.client.rawcommand(args) except CommandError as e: raise SourceControlError('commit', e.out, e.args, e.out) def revert(self, paths=None): - with cl_lock: - if paths is not None: - self.client.revert(files=paths, nobackup=True) - else: - self.client.revert(all=True, nobackup=True) + if paths is not None: + self.client.revert(files=paths, nobackup=True) + else: + self.client.revert(all=True, nobackup=True)