##// END OF EJS Templates
hgweb: return content iterator instead of using write() callable
hgweb: return content iterator instead of using write() callable

File last commit:

r6782:b9d6ab18 default
r6785:4879468f default
Show More
streamclone.py
91 lines | 3.1 KiB | text/x-python | PythonLexer
Vadim Gelfer
add support for streaming clone....
r2612 # streamclone.py - streaming clone server support for mercurial
#
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 import os, osutil, stat, util, lock
Vadim Gelfer
add support for streaming clone....
r2612
# if server supports streaming clone, it advertises "stream"
# capability with value that is version+flags of repo it is serving.
# client only streams if it can read that repo format.
def walkrepo(root):
'''iterate over metadata files in repository.
walk in natural (sorted) order.
yields 2-tuples: name of .d or .i file, size of file.'''
strip_count = len(root) + len(os.sep)
def walk(path, recurse):
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 for e, kind, st in osutil.listdir(path, stat=True):
Vadim Gelfer
add support for streaming clone....
r2612 pe = os.path.join(path, e)
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 if kind == stat.S_IFDIR:
Vadim Gelfer
add support for streaming clone....
r2612 if recurse:
for x in walk(pe, True):
yield x
else:
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 if kind != stat.S_IFREG or len(e) < 2:
Vadim Gelfer
add support for streaming clone....
r2612 continue
sfx = e[-2:]
if sfx in ('.d', '.i'):
yield pe[strip_count:], st.st_size
# write file data first
for x in walk(os.path.join(root, 'data'), True):
yield x
# write manifest before changelog
Matt Mackall
util: add sort helper
r6762 meta = util.sort(walk(root, False))
Vadim Gelfer
fix problem with uncompressed clone and python 2.3.
r2623 meta.reverse()
Vadim Gelfer
add support for streaming clone....
r2612 for x in meta:
yield x
# stream file format is simple.
#
# server writes out line that says how many files, how many total
# bytes. separator is ascii space, byte counts are strings.
#
# then for each file:
#
# server writes out line that says file name, how many bytes in
# file. separator is ascii nul, byte count is string.
#
# server writes out raw file data.
Dirkjan Ochtman
streamclone yields chunks instead of accepting a file-like object
r6782 def stream_out(repo, untrusted=False):
Vadim Gelfer
add support for streaming clone....
r2612 '''stream out all metadata files in repository.
writes to file-like object, must support write() and optional flush().'''
Vadim Gelfer
clone: disable stream support on server side by default....
r2621
Edouard Gomez
Fix inconsistency for the stream_out capability in hgweb...
r4834 if not repo.ui.configbool('server', 'uncompressed', untrusted=untrusted):
Dirkjan Ochtman
streamclone yields chunks instead of accepting a file-like object
r6782 yield '1\n'
Vadim Gelfer
clone: disable stream support on server side by default....
r2621 return
Vadim Gelfer
add support for streaming clone....
r2612 # get consistent snapshot of repo. lock during scan so lock not
# needed while we stream, and commits can happen.
Benoit Boissinot
fix typo
r5456 repolock = None
Thomas Arendsen Hein
Handle locking exceptions if streaming clone can't lock the repo. (Issue324)
r3687 try:
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
repolock = repo.lock()
except (lock.LockHeld, lock.LockUnavailable), inst:
repo.ui.warn('locking the repository failed: %s\n' % (inst,))
Dirkjan Ochtman
streamclone yields chunks instead of accepting a file-like object
r6782 yield '2\n'
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 return
Thomas Arendsen Hein
Handle locking exceptions if streaming clone can't lock the repo. (Issue324)
r3687
Dirkjan Ochtman
streamclone yields chunks instead of accepting a file-like object
r6782 yield '0\n'
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 repo.ui.debug('scanning\n')
entries = []
total_bytes = 0
for name, size in walkrepo(repo.spath):
name = repo.decodefn(util.pconvert(name))
entries.append((name, size))
total_bytes += size
finally:
del repolock
Vadim Gelfer
add support for streaming clone....
r2612
repo.ui.debug('%d files, %d bytes to transfer\n' %
(len(entries), total_bytes))
Dirkjan Ochtman
streamclone yields chunks instead of accepting a file-like object
r6782 yield '%d %d\n' % (len(entries), total_bytes)
Vadim Gelfer
add support for streaming clone....
r2612 for name, size in entries:
repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
Dirkjan Ochtman
streamclone yields chunks instead of accepting a file-like object
r6782 yield '%s\0%d\n' % (name, size)
Benoit Boissinot
introduce localrepo.spath for the store path, sopener fixes
r3791 for chunk in util.filechunkiter(repo.sopener(name), limit=size):
Dirkjan Ochtman
streamclone yields chunks instead of accepting a file-like object
r6782 yield chunk