##// END OF EJS Templates
protocol: convert StreamException to generated error code...
Dirkjan Ochtman -
r11624:67260651 default
parent child Browse files
Show More
@@ -1,69 +1,63 b''
1 # streamclone.py - streaming clone server support for mercurial
1 # streamclone.py - streaming clone server support for mercurial
2 #
2 #
3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 import util, error
8 import util, error
9
10 from mercurial import store
9 from mercurial import store
11
10
12 class StreamException(Exception):
13 def __init__(self, code):
14 Exception.__init__(self)
15 self.code = code
16 def __str__(self):
17 return '%i\n' % self.code
18
19 # if server supports streaming clone, it advertises "stream"
11 # if server supports streaming clone, it advertises "stream"
20 # capability with value that is version+flags of repo it is serving.
12 # capability with value that is version+flags of repo it is serving.
21 # client only streams if it can read that repo format.
13 # client only streams if it can read that repo format.
22
14
23 # stream file format is simple.
15 # stream file format is simple.
24 #
16 #
25 # server writes out line that says how many files, how many total
17 # server writes out line that says how many files, how many total
26 # bytes. separator is ascii space, byte counts are strings.
18 # bytes. separator is ascii space, byte counts are strings.
27 #
19 #
28 # then for each file:
20 # then for each file:
29 #
21 #
30 # server writes out line that says filename, how many bytes in
22 # server writes out line that says filename, how many bytes in
31 # file. separator is ascii nul, byte count is string.
23 # file. separator is ascii nul, byte count is string.
32 #
24 #
33 # server writes out raw file data.
25 # server writes out raw file data.
34
26
35 def allowed(ui):
27 def allowed(ui):
36 return ui.configbool('server', 'uncompressed', True, untrusted=True)
28 return ui.configbool('server', 'uncompressed', True, untrusted=True)
37
29
38 def stream_out(repo):
30 def stream_out(repo):
39 '''stream out all metadata files in repository.
31 '''stream out all metadata files in repository.
40 writes to file-like object, must support write() and optional flush().'''
32 writes to file-like object, must support write() and optional flush().'''
41
33
42 if not allowed(repo.ui):
34 if not allowed(repo.ui):
43 raise StreamException(1)
35 yield '1\n' # error: 1
36 return
44
37
45 entries = []
38 entries = []
46 total_bytes = 0
39 total_bytes = 0
47 try:
40 try:
48 # get consistent snapshot of repo, lock during scan
41 # get consistent snapshot of repo, lock during scan
49 lock = repo.lock()
42 lock = repo.lock()
50 try:
43 try:
51 repo.ui.debug('scanning\n')
44 repo.ui.debug('scanning\n')
52 for name, ename, size in repo.store.walk():
45 for name, ename, size in repo.store.walk():
53 entries.append((name, size))
46 entries.append((name, size))
54 total_bytes += size
47 total_bytes += size
55 finally:
48 finally:
56 lock.release()
49 lock.release()
57 except error.LockError:
50 except error.LockError:
58 raise StreamException(2)
51 yield '2\n' # error: 2
52 return
59
53
60 yield '0\n'
54 yield '0\n' # success
61 repo.ui.debug('%d files, %d bytes to transfer\n' %
55 repo.ui.debug('%d files, %d bytes to transfer\n' %
62 (len(entries), total_bytes))
56 (len(entries), total_bytes))
63 yield '%d %d\n' % (len(entries), total_bytes)
57 yield '%d %d\n' % (len(entries), total_bytes)
64 for name, size in entries:
58 for name, size in entries:
65 repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
59 repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
66 # partially encode name over the wire for backwards compat
60 # partially encode name over the wire for backwards compat
67 yield '%s\0%d\n' % (store.encodedir(name), size)
61 yield '%s\0%d\n' % (store.encodedir(name), size)
68 for chunk in util.filechunkiter(repo.sopener(name), limit=size):
62 for chunk in util.filechunkiter(repo.sopener(name), limit=size):
69 yield chunk
63 yield chunk
General Comments 0
You need to be logged in to leave comments. Login now