__init__.py
110 lines
| 3.8 KiB
| text/x-python
|
PythonLexer
|
r6239 | # __init__.py - inotify-based status acceleration for Linux | ||
# | ||||
# Copyright 2006, 2007, 2008 Bryan O'Sullivan <bos@serpentine.com> | ||||
# Copyright 2007, 2008 Brendan Cully <brendan@kublai.com> | ||||
# | ||||
|
r8225 | # This software may be used and distributed according to the terms of the | ||
# GNU General Public License version 2, incorporated herein by reference. | ||||
|
r6239 | |||
'''inotify-based status acceleration for Linux systems | ||||
''' | ||||
# todo: socket permissions | ||||
|
r7225 | from mercurial.i18n import _ | ||
|
r6239 | from mercurial import cmdutil, util | ||
|
r8656 | import server | ||
|
r6239 | from weakref import proxy | ||
|
r8552 | from client import client, QueryFailed | ||
|
r6239 | |||
def serve(ui, repo, **opts): | ||||
'''start an inotify server for this repository''' | ||||
timeout = opts.get('timeout') | ||||
if timeout: | ||||
timeout = float(timeout) * 1e3 | ||||
class service: | ||||
def init(self): | ||||
|
r6995 | try: | ||
|
r8385 | self.master = server.master(ui, repo, timeout) | ||
|
r6995 | except server.AlreadyStartedException, inst: | ||
raise util.Abort(str(inst)) | ||||
|
r6239 | |||
def run(self): | ||||
try: | ||||
self.master.run() | ||||
finally: | ||||
self.master.shutdown() | ||||
service = service() | ||||
cmdutil.service(opts, initfn=service.init, runfn=service.run) | ||||
|
r8555 | def debuginotify(ui, repo, **opts): | ||
'''debugging information for inotify extension | ||||
Prints the list of directories being watched by the inotify server. | ||||
''' | ||||
cli = client(ui, repo) | ||||
response = cli.debugquery() | ||||
ui.write(_('directories being watched:\n')) | ||||
for path in response: | ||||
ui.write((' %s/\n') % path) | ||||
|
r6239 | def reposetup(ui, repo): | ||
|
r7522 | if not hasattr(repo, 'dirstate'): | ||
|
r6239 | return | ||
# XXX: weakref until hg stops relying on __del__ | ||||
repo = proxy(repo) | ||||
class inotifydirstate(repo.dirstate.__class__): | ||||
|
r8556 | # We'll set this to false after an unsuccessful attempt so that | ||
# next calls of status() within the same instance don't try again | ||||
# to start an inotify server if it won't start. | ||||
_inotifyon = True | ||||
|
r6753 | def status(self, match, ignored, clean, unknown=True): | ||
|
r6603 | files = match.files() | ||
|
r7393 | if '.' in files: | ||
|
r7434 | files = [] | ||
|
r8557 | if self._inotifyon and not ignored: | ||
|
r8552 | cli = client(ui, repo) | ||
try: | ||||
|
r8551 | result = cli.statusquery(files, match, False, | ||
|
r8552 | clean, unknown) | ||
except QueryFailed, instr: | ||||
ui.debug(str(instr)) | ||||
|
r8556 | # don't retry within the same hg instance | ||
inotifydirstate._inotifyon = False | ||||
|
r8552 | pass | ||
else: | ||||
if ui.config('inotify', 'debug'): | ||||
|
r7219 | r2 = super(inotifydirstate, self).status( | ||
match, False, clean, unknown) | ||||
for c,a,b in zip('LMARDUIC', result, r2): | ||||
for f in a: | ||||
if f not in b: | ||||
ui.warn('*** inotify: %s +%s\n' % (c, f)) | ||||
for f in b: | ||||
if f not in a: | ||||
|
r7304 | ui.warn('*** inotify: %s -%s\n' % (c, f)) | ||
|
r7219 | result = r2 | ||
|
r8552 | return result | ||
|
r6239 | return super(inotifydirstate, self).status( | ||
|
r6753 | match, ignored, clean, unknown) | ||
|
r6239 | |||
repo.dirstate.__class__ = inotifydirstate | ||||
cmdtable = { | ||||
|
r8555 | 'debuginotify': | ||
(debuginotify, [], ('hg debuginotify')), | ||||
|
r6239 | '^inserve': | ||
|
r8555 | (serve, | ||
[('d', 'daemon', None, _('run server in background')), | ||||
('', 'daemon-pipefds', '', _('used internally by daemon mode')), | ||||
('t', 'idle-timeout', '', _('minutes to sit idle before exiting')), | ||||
('', 'pid-file', '', _('name of file to write process ID to'))], | ||||
_('hg inserve [OPT]...')), | ||||
|
r6239 | } | ||