##// END OF EJS Templates
server: add an error feedback mechanism for when the daemon fails to launch...
server: add an error feedback mechanism for when the daemon fails to launch There's a recurring problem on Windows where `hg serve -d` will randomly fail to spawn a detached process. The reason for the failure is completely hidden, and it takes hours to get a single failure on my laptop. All this does is redirect stdout/stderr of the child to a file until the lock file is freed, and then the parent dumps it out if it fails to spawn. I chose to put the output into the lock file because that is always cleaned up. There's no way to report errors after that anyway. On Windows, killdaemons.py is roughly `kill -9`, so this ensures that junk won't pile up. This may end up being a case of EADDRINUSE. At least that's what I saw spit out a few times (among other odd errors and missing output on Windows). But I also managed to get the same thing on Fedora 26 by running test-hgwebdir.t with --loop -j10 for several hours. Running `netstat` immediately after killing that run printed a wall of sockets in the TIME_WAIT state, which were gone a couple seconds later. I couldn't match up ports that failed, because --loop doesn't print out the message about the port that was used. So maybe the fix is to rotate the use of HGPORT[12] in the tests. But, let's collect some more data first.

File last commit:

r36489:c28b6d60 default
r37229:f09a2eab default
Show More
narrowrepo.py
86 lines | 3.2 KiB | text/x-python | PythonLexer
# narrowrepo.py - repository which supports narrow revlogs, lazy loading
#
# Copyright 2017 Google, 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 (
bundlerepo,
changegroup,
hg,
localrepo,
narrowspec,
scmutil,
)
from . import (
narrowrevlog,
)
def wrappostshare(orig, sourcerepo, destrepo, **kwargs):
orig(sourcerepo, destrepo, **kwargs)
if changegroup.NARROW_REQUIREMENT in sourcerepo.requirements:
with destrepo.wlock():
with destrepo.vfs('shared', 'a') as fp:
fp.write(narrowspec.FILENAME + '\n')
def unsharenarrowspec(orig, ui, repo, repopath):
if (changegroup.NARROW_REQUIREMENT in repo.requirements
and repo.path == repopath and repo.shared()):
srcrepo = hg.sharedreposource(repo)
with srcrepo.vfs(narrowspec.FILENAME) as f:
spec = f.read()
with repo.vfs(narrowspec.FILENAME, 'w') as f:
f.write(spec)
return orig(ui, repo, repopath)
def wraprepo(repo):
"""Enables narrow clone functionality on a single local repository."""
cacheprop = localrepo.storecache
if isinstance(repo, bundlerepo.bundlerepository):
# We have to use a different caching property decorator for
# bundlerepo because storecache blows up in strange ways on a
# bundlerepo. Fortunately, there's no risk of data changing in
# a bundlerepo.
cacheprop = lambda name: localrepo.unfilteredpropertycache
class narrowrepository(repo.__class__):
def _constructmanifest(self):
manifest = super(narrowrepository, self)._constructmanifest()
narrowrevlog.makenarrowmanifestrevlog(manifest, repo)
return manifest
@cacheprop('00manifest.i')
def manifestlog(self):
mfl = super(narrowrepository, self).manifestlog
narrowrevlog.makenarrowmanifestlog(mfl, self)
return mfl
def file(self, f):
fl = super(narrowrepository, self).file(f)
narrowrevlog.makenarrowfilelog(fl, self.narrowmatch())
return fl
# I'm not sure this is the right place to do this filter.
# context._manifestmatches() would probably be better, or perhaps
# move it to a later place, in case some of the callers do want to know
# which directories changed. This seems to work for now, though.
def status(self, *args, **kwargs):
s = super(narrowrepository, self).status(*args, **kwargs)
narrowmatch = self.narrowmatch()
modified = list(filter(narrowmatch, s.modified))
added = list(filter(narrowmatch, s.added))
removed = list(filter(narrowmatch, s.removed))
deleted = list(filter(narrowmatch, s.deleted))
unknown = list(filter(narrowmatch, s.unknown))
ignored = list(filter(narrowmatch, s.ignored))
clean = list(filter(narrowmatch, s.clean))
return scmutil.status(modified, added, removed, deleted, unknown,
ignored, clean)
repo.__class__ = narrowrepository