Mercurial > hg
view hgext/remotefilelog/connectionpool.py @ 40495:3a333a582d7b
remotefilelog: import pruned-down remotefilelog extension from hg-experimental
This is remotefilelog as of my recent patches for compatibility with
current tip of hg, minus support for old versions of Mercurial and
some FB-specific features like their treemanifest extension and
fetching linkrev data from a patched phabricator. The file extutil.py
moved from hgext3rd to remotefilelog.
This is not yet ready to be landed, consider it a preview for
now. Planned changes include:
* replace lz4 with zstd
* rename some capabilities, requirements and wireproto commands to mark
them as experimental
* consolidate bits of shallowutil with related functions (eg readfile)
I'm certainly open to other (small) changes, but my rough mission is
to land this largely as-is so we can use it as a model of the
functionality we need going forward for lazy-fetching of file contents
from a server.
# no-check-commit because of a few foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D4782
author | Augie Fackler <augie@google.com> |
---|---|
date | Thu, 27 Sep 2018 13:03:19 -0400 |
parents | |
children | 2372284d9457 |
line wrap: on
line source
# connectionpool.py - class for pooling peer connections for reuse # # Copyright 2017 Facebook, Inc. # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from __future__ import absolute_import from mercurial import ( extensions, hg, sshpeer, util, ) _sshv1peer = sshpeer.sshv1peer class connectionpool(object): def __init__(self, repo): self._repo = repo self._pool = dict() def get(self, path): pathpool = self._pool.get(path) if pathpool is None: pathpool = list() self._pool[path] = pathpool conn = None if len(pathpool) > 0: try: conn = pathpool.pop() peer = conn.peer # If the connection has died, drop it if isinstance(peer, _sshv1peer): if peer._subprocess.poll() is not None: conn = None except IndexError: pass if conn is None: def _cleanup(orig): # close pipee first so peer.cleanup reading it won't deadlock, # if there are other processes with pipeo open (i.e. us). peer = orig.im_self if util.safehasattr(peer, 'pipee'): peer.pipee.close() return orig() peer = hg.peer(self._repo.ui, {}, path) if util.safehasattr(peer, 'cleanup'): extensions.wrapfunction(peer, 'cleanup', _cleanup) conn = connection(pathpool, peer) return conn def close(self): for pathpool in self._pool.itervalues(): for conn in pathpool: conn.close() del pathpool[:] class connection(object): def __init__(self, pool, peer): self._pool = pool self.peer = peer def __enter__(self): return self def __exit__(self, type, value, traceback): # Only add the connection back to the pool if there was no exception, # since an exception could mean the connection is not in a reusable # state. if type is None: self._pool.append(self) else: self.close() def close(self): if util.safehasattr(self.peer, 'cleanup'): self.peer.cleanup()