##// END OF EJS Templates
inotify: modular architecture for inotify clients...
Nicolas Dumazet -
r8551:7089d972 default
parent child Browse files
Show More
@@ -13,8 +13,9
13
13
14 from mercurial.i18n import _
14 from mercurial.i18n import _
15 from mercurial import cmdutil, util
15 from mercurial import cmdutil, util
16 import client, errno, os, server, socket
16 import errno, os, server, socket
17 from weakref import proxy
17 from weakref import proxy
18 from client import client
18
19
19 def serve(ui, repo, **opts):
20 def serve(ui, repo, **opts):
20 '''start an inotify server for this repository'''
21 '''start an inotify server for this repository'''
@@ -54,9 +55,10 def reposetup(ui, repo):
54 files = match.files()
55 files = match.files()
55 if '.' in files:
56 if '.' in files:
56 files = []
57 files = []
58 cli = client(ui, repo)
57 try:
59 try:
58 if not ignored and not self.inotifyserver:
60 if not ignored and not self.inotifyserver:
59 result = client.query(ui, repo, files, match, False,
61 result = cli.statusquery(files, match, False,
60 clean, unknown)
62 clean, unknown)
61 if result and ui.config('inotify', 'debug'):
63 if result and ui.config('inotify', 'debug'):
62 r2 = super(inotifydirstate, self).status(
64 r2 = super(inotifydirstate, self).status(
@@ -94,8 +96,8 def reposetup(ui, repo):
94 else:
96 else:
95 # server is started, send query again
97 # server is started, send query again
96 try:
98 try:
97 return client.query(ui, repo, files, match,
99 return cli.statusquery(files, match, ignored,
98 ignored, clean, unknown)
100 clean, unknown)
99 except socket.error, err:
101 except socket.error, err:
100 ui.warn(_('could not talk to new inotify '
102 ui.warn(_('could not talk to new inotify '
101 'server: %s\n') % err[-1])
103 'server: %s\n') % err[-1])
@@ -2,6 +2,7
2 #
2 #
3 # Copyright 2006, 2007, 2008 Bryan O'Sullivan <bos@serpentine.com>
3 # Copyright 2006, 2007, 2008 Bryan O'Sullivan <bos@serpentine.com>
4 # Copyright 2007, 2008 Brendan Cully <brendan@kublai.com>
4 # Copyright 2007, 2008 Brendan Cully <brendan@kublai.com>
5 # Copyright 2009 Nicolas Dumazet <nicdumz@gmail.com>
5 #
6 #
6 # This software may be used and distributed according to the terms of the
7 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2, incorporated herein by reference.
8 # GNU General Public License version 2, incorporated herein by reference.
@@ -10,18 +11,62 from mercurial.i18n import _
10 import common
11 import common
11 import os, socket, struct
12 import os, socket, struct
12
13
13 def query(ui, repo, names, match, ignored, clean, unknown=True):
14 class client(object):
14 sock = socket.socket(socket.AF_UNIX)
15 def __init__(self, ui, repo):
15 sockpath = repo.join('inotify.sock')
16 self.ui = ui
17 self.repo = repo
18 self.sock = socket.socket(socket.AF_UNIX)
19
20 def _connect(self):
21 sockpath = self.repo.join('inotify.sock')
16 try:
22 try:
17 sock.connect(sockpath)
23 self.sock.connect(sockpath)
18 except socket.error, err:
24 except socket.error, err:
19 if err[0] == "AF_UNIX path too long":
25 if err[0] == "AF_UNIX path too long":
20 sockpath = os.readlink(sockpath)
26 sockpath = os.readlink(sockpath)
21 sock.connect(sockpath)
27 self.sock.connect(sockpath)
22 else:
28 else:
23 raise
29 raise
24
30
31 def _send(self, data):
32 """Sends protocol version number, and the data"""
33 self.sock.sendall(chr(common.version) + data)
34
35 self.sock.shutdown(socket.SHUT_WR)
36
37 def _receive(self):
38 """
39 Read data, check version number, extract headers,
40 and returns a tuple (data descriptor, header)
41 Returns (None, None) on error
42 """
43 cs = common.recvcs(self.sock)
44 version = ord(cs.read(1))
45 if version != common.version:
46 self.ui.warn(_('(inotify: received response from incompatible '
47 'server version %d)\n') % version)
48 return None, None
49
50 # only one type of request is supported for now
51 type = 'STAT'
52 hdrfmt = common.resphdrfmts[type]
53 hdrsize = common.resphdrsizes[type]
54 try:
55 resphdr = struct.unpack(hdrfmt, cs.read(hdrsize))
56 except struct.error:
57 return None, None
58
59 return cs, resphdr
60
61 def query(self, req):
62 self._connect()
63
64 self._send(req)
65
66 return self._receive()
67
68 def statusquery(self, names, match, ignored, clean, unknown=True):
69
25 def genquery():
70 def genquery():
26 for n in names:
71 for n in names:
27 yield n
72 yield n
@@ -34,25 +79,9 def query(ui, repo, names, match, ignore
34
79
35 req = '\0'.join(genquery())
80 req = '\0'.join(genquery())
36
81
37 sock.sendall(chr(common.version))
82 cs, resphdr = self.query(req)
38 sock.sendall(req)
39 sock.shutdown(socket.SHUT_WR)
40
41 cs = common.recvcs(sock)
42 version = ord(cs.read(1))
43
83
44 if version != common.version:
84 if not cs:
45 ui.warn(_('(inotify: received response from incompatible server '
46 'version %d)\n') % version)
47 return None
48
49 # only one type of request is supported for now
50 type = 'STAT'
51 hdrfmt = common.resphdrfmts[type]
52 hdrsize = common.resphdrsizes[type]
53 try:
54 resphdr = struct.unpack(hdrfmt, cs.read(hdrsize))
55 except struct.error:
56 return None
85 return None
57
86
58 def readnames(nbytes):
87 def readnames(nbytes):
General Comments 0
You need to be logged in to leave comments. Login now