##// END OF EJS Templates
inotify: Separate query sending logic from Server starting....
Nicolas Dumazet -
r8552:06561793 default
parent child Browse files
Show More
@@ -13,9 +13,9 b''
13 13
14 14 from mercurial.i18n import _
15 15 from mercurial import cmdutil, util
16 import errno, os, server, socket
16 import os, server
17 17 from weakref import proxy
18 from client import client
18 from client import client, QueryFailed
19 19
20 20 def serve(ui, repo, **opts):
21 21 '''start an inotify server for this repository'''
@@ -55,12 +55,16 b' def reposetup(ui, repo):'
55 55 files = match.files()
56 56 if '.' in files:
57 57 files = []
58 cli = client(ui, repo)
59 try:
60 if not ignored and not self.inotifyserver:
58 if not ignored and not self.inotifyserver:
59 cli = client(ui, repo)
60 try:
61 61 result = cli.statusquery(files, match, False,
62 clean, unknown)
63 if result and ui.config('inotify', 'debug'):
62 clean, unknown)
63 except QueryFailed, instr:
64 ui.debug(str(instr))
65 pass
66 else:
67 if ui.config('inotify', 'debug'):
64 68 r2 = super(inotifydirstate, self).status(
65 69 match, False, clean, unknown)
66 70 for c,a,b in zip('LMARDUIC', result, r2):
@@ -71,46 +75,7 b' def reposetup(ui, repo):'
71 75 if f not in a:
72 76 ui.warn('*** inotify: %s -%s\n' % (c, f))
73 77 result = r2
74
75 if result is not None:
76 return result
77 except (OSError, socket.error), err:
78 autostart = ui.configbool('inotify', 'autostart', True)
79
80 if err[0] == errno.ECONNREFUSED:
81 ui.warn(_('(found dead inotify server socket; '
82 'removing it)\n'))
83 os.unlink(repo.join('inotify.sock'))
84 if err[0] in (errno.ECONNREFUSED, errno.ENOENT) and autostart:
85 ui.debug(_('(starting inotify server)\n'))
86 try:
87 try:
88 server.start(ui, repo)
89 except server.AlreadyStartedException, inst:
90 # another process may have started its own
91 # inotify server while this one was starting.
92 ui.debug(str(inst))
93 except Exception, inst:
94 ui.warn(_('could not start inotify server: '
95 '%s\n') % inst)
96 else:
97 # server is started, send query again
98 try:
99 return cli.statusquery(files, match, ignored,
100 clean, unknown)
101 except socket.error, err:
102 ui.warn(_('could not talk to new inotify '
103 'server: %s\n') % err[-1])
104 elif err[0] in (errno.ECONNREFUSED, errno.ENOENT):
105 # silently ignore normal errors if autostart is False
106 ui.debug(_('(inotify server not running)\n'))
107 else:
108 ui.warn(_('failed to contact inotify server: %s\n')
109 % err[-1])
110 ui.traceback()
111 # replace by old status function
112 self.status = super(inotifydirstate, self).status
113
78 return result
114 79 return super(inotifydirstate, self).status(
115 80 match, ignored, clean, unknown)
116 81
@@ -8,8 +8,58 b''
8 8 # GNU General Public License version 2, incorporated herein by reference.
9 9
10 10 from mercurial.i18n import _
11 import common
12 import os, socket, struct
11 import common, server
12 import errno, os, socket, struct
13
14 class QueryFailed(Exception): pass
15
16 def start_server(function):
17 """
18 Decorator.
19 Tries to call function, if it fails, try to (re)start inotify server.
20 Raise QueryFailed if something went wrong
21 """
22 def decorated_function(self, *args):
23 result = None
24 try:
25 return function(self, *args)
26 except (OSError, socket.error), err:
27 autostart = self.ui.configbool('inotify', 'autostart', True)
28
29 if err[0] == errno.ECONNREFUSED:
30 self.ui.warn(_('(found dead inotify server socket; '
31 'removing it)\n'))
32 os.unlink(self.repo.join('inotify.sock'))
33 if err[0] in (errno.ECONNREFUSED, errno.ENOENT) and autostart:
34 self.ui.debug(_('(starting inotify server)\n'))
35 try:
36 try:
37 server.start(self.ui, self.repo)
38 except server.AlreadyStartedException, inst:
39 # another process may have started its own
40 # inotify server while this one was starting.
41 self.ui.debug(str(inst))
42 except Exception, inst:
43 self.ui.warn(_('could not start inotify server: '
44 '%s\n') % inst)
45 else:
46 try:
47 return function(self, *args)
48 except socket.error, err:
49 self.ui.warn(_('could not talk to new inotify '
50 'server: %s\n') % err[-1])
51 elif err[0] in (errno.ECONNREFUSED, errno.ENOENT):
52 # silently ignore normal errors if autostart is False
53 self.ui.debug(_('(inotify server not running)\n'))
54 else:
55 self.ui.warn(_('failed to contact inotify server: %s\n')
56 % err[-1])
57
58 self.ui.traceback()
59 raise QueryFailed('inotify query failed')
60
61 return decorated_function
62
13 63
14 64 class client(object):
15 65 def __init__(self, ui, repo):
@@ -38,14 +88,14 b' class client(object):'
38 88 """
39 89 Read data, check version number, extract headers,
40 90 and returns a tuple (data descriptor, header)
41 Returns (None, None) on error
91 Raises QueryFailed on error
42 92 """
43 93 cs = common.recvcs(self.sock)
44 94 version = ord(cs.read(1))
45 95 if version != common.version:
46 96 self.ui.warn(_('(inotify: received response from incompatible '
47 97 'server version %d)\n') % version)
48 return None, None
98 raise QueryFailed('incompatible server version')
49 99
50 100 # only one type of request is supported for now
51 101 type = 'STAT'
@@ -54,7 +104,7 b' class client(object):'
54 104 try:
55 105 resphdr = struct.unpack(hdrfmt, cs.read(hdrsize))
56 106 except struct.error:
57 return None, None
107 raise QueryFailed('unable to retrieve query response headers')
58 108
59 109 return cs, resphdr
60 110
@@ -65,6 +115,7 b' class client(object):'
65 115
66 116 return self._receive()
67 117
118 @start_server
68 119 def statusquery(self, names, match, ignored, clean, unknown=True):
69 120
70 121 def genquery():
@@ -81,9 +132,6 b' class client(object):'
81 132
82 133 cs, resphdr = self.query(req)
83 134
84 if not cs:
85 return None
86
87 135 def readnames(nbytes):
88 136 if nbytes:
89 137 names = cs.read(nbytes)
General Comments 0
You need to be logged in to leave comments. Login now