annotate mercurial/streamclone.py @ 6945:2cfdabe235fb

hgweb: return content iterator instead of using write() callable This is a new version of 4879468fa28f (which was backed out in 943f066c0d58), with an extra line removed to fix problems with hg serve. hg's internal web server contains checking if the app isn't trying to write more bytes than specified by the Content-Length header. The first try still contained an old line that wrote the response, so the response was sent twice.
author Dirkjan Ochtman <dirkjan@ochtman.nl>
date Sat, 30 Aug 2008 17:13:23 +0200
parents 87abfefafe02
children 63b5f4c73c98
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2612
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
1 # streamclone.py - streaming clone server support for mercurial
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
2 #
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
4 #
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
6 # of the GNU General Public License, incorporated herein by reference.
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
7
6840
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6794
diff changeset
8 import util, lock
2612
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
9
6925
87abfefafe02 make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6901
diff changeset
10 class StreamException(Exception):
87abfefafe02 make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6901
diff changeset
11 def __init__(self, code):
87abfefafe02 make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6901
diff changeset
12 Exception.__init__(self)
87abfefafe02 make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6901
diff changeset
13 self.code = code
87abfefafe02 make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6901
diff changeset
14 def __str__(self):
87abfefafe02 make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6901
diff changeset
15 return '%i\n' % self.code
87abfefafe02 make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6901
diff changeset
16
2612
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
17 # if server supports streaming clone, it advertises "stream"
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
18 # capability with value that is version+flags of repo it is serving.
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
19 # client only streams if it can read that repo format.
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
20
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
21 # stream file format is simple.
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
22 #
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
23 # server writes out line that says how many files, how many total
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
24 # bytes. separator is ascii space, byte counts are strings.
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
25 #
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
26 # then for each file:
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
27 #
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
28 # server writes out line that says file name, how many bytes in
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
29 # file. separator is ascii nul, byte count is string.
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
30 #
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
31 # server writes out raw file data.
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
32
6925
87abfefafe02 make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6901
diff changeset
33 def stream_out(repo, untrusted=False):
2612
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
34 '''stream out all metadata files in repository.
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
35 writes to file-like object, must support write() and optional flush().'''
2621
5a5852a417b1 clone: disable stream support on server side by default.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2612
diff changeset
36
4834
439e2f2fde42 Fix inconsistency for the stream_out capability in hgweb
Edouard Gomez <ed.gomez@free.fr>
parents: 4134
diff changeset
37 if not repo.ui.configbool('server', 'uncompressed', untrusted=untrusted):
6925
87abfefafe02 make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6901
diff changeset
38 raise StreamException(1)
2621
5a5852a417b1 clone: disable stream support on server side by default.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2612
diff changeset
39
6901
43a817f3a649 streamclone: fold in localrepo.storefiles
Matt Mackall <mpm@selenic.com>
parents: 6840
diff changeset
40 entries = []
43a817f3a649 streamclone: fold in localrepo.storefiles
Matt Mackall <mpm@selenic.com>
parents: 6840
diff changeset
41 total_bytes = 0
3687
d5dd0a2a44bc Handle locking exceptions if streaming clone can't lock the repo. (Issue324)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2623
diff changeset
42 try:
6901
43a817f3a649 streamclone: fold in localrepo.storefiles
Matt Mackall <mpm@selenic.com>
parents: 6840
diff changeset
43 l = None
43a817f3a649 streamclone: fold in localrepo.storefiles
Matt Mackall <mpm@selenic.com>
parents: 6840
diff changeset
44 try:
43a817f3a649 streamclone: fold in localrepo.storefiles
Matt Mackall <mpm@selenic.com>
parents: 6840
diff changeset
45 repo.ui.debug('scanning\n')
43a817f3a649 streamclone: fold in localrepo.storefiles
Matt Mackall <mpm@selenic.com>
parents: 6840
diff changeset
46 # get consistent snapshot of repo, lock during scan
43a817f3a649 streamclone: fold in localrepo.storefiles
Matt Mackall <mpm@selenic.com>
parents: 6840
diff changeset
47 l = repo.lock()
43a817f3a649 streamclone: fold in localrepo.storefiles
Matt Mackall <mpm@selenic.com>
parents: 6840
diff changeset
48 for name, ename, size in repo.store.walk():
43a817f3a649 streamclone: fold in localrepo.storefiles
Matt Mackall <mpm@selenic.com>
parents: 6840
diff changeset
49 entries.append((name, size))
43a817f3a649 streamclone: fold in localrepo.storefiles
Matt Mackall <mpm@selenic.com>
parents: 6840
diff changeset
50 total_bytes += size
43a817f3a649 streamclone: fold in localrepo.storefiles
Matt Mackall <mpm@selenic.com>
parents: 6840
diff changeset
51 finally:
43a817f3a649 streamclone: fold in localrepo.storefiles
Matt Mackall <mpm@selenic.com>
parents: 6840
diff changeset
52 del l
6840
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6794
diff changeset
53 except (lock.LockHeld, lock.LockUnavailable), inst:
6925
87abfefafe02 make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6901
diff changeset
54 raise StreamException(2)
3687
d5dd0a2a44bc Handle locking exceptions if streaming clone can't lock the repo. (Issue324)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2623
diff changeset
55
6925
87abfefafe02 make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6901
diff changeset
56 yield '0\n'
2612
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
57 repo.ui.debug('%d files, %d bytes to transfer\n' %
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
58 (len(entries), total_bytes))
6925
87abfefafe02 make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6901
diff changeset
59 yield '%d %d\n' % (len(entries), total_bytes)
2612
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
60 for name, size in entries:
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
61 repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
6925
87abfefafe02 make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6901
diff changeset
62 yield '%s\0%d\n' % (name, size)
3791
8643b9f90b51 introduce localrepo.spath for the store path, sopener fixes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3721
diff changeset
63 for chunk in util.filechunkiter(repo.sopener(name), limit=size):
6925
87abfefafe02 make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6901
diff changeset
64 yield chunk