[PATCH 2 of 4 modernize-streamclone] streamclone: move payload header generation into own function
Gregory Szorc
gregory.szorc at gmail.com
Sun Oct 4 21:32:38 CDT 2015
# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1444010766 25200
# Sun Oct 04 19:06:06 2015 -0700
# Node ID 39d3757d69f177811d0503fd1d770f504eb6e099
# Parent dc56645d890d688f5df4fcafa8568930a7d9eca7
streamclone: move payload header generation into own function
The stream clone data over the wire protocol contains a header line
indicating total file count and data size. In bundle2, this metadata can
be captured by a part parameter and doesn't need to be in the body.
In preparation for bundle2, have generatev1() return the raw metadata
and move the header generation to its own function.
diff --git a/mercurial/streamclone.py b/mercurial/streamclone.py
--- a/mercurial/streamclone.py
+++ b/mercurial/streamclone.py
@@ -163,15 +163,14 @@ def _walkstreamfiles(repo):
def generatev1(repo):
"""Emit content for version 1 of a streaming clone.
- This is a generator of raw chunks that constitute a streaming clone.
+ This returns a 3-tuple of (file count, byte size, data iterator).
- The stream begins with a line of 2 space-delimited integers containing the
- number of entries and total bytes size.
+ The data iterator consists of N entries for each file being transferred.
+ Each file entry starts as a line with the file name and integer size
+ delimited by a null byte.
- Next, are N entries for each file being transferred. Each file entry starts
- as a line with the file name and integer size delimited by a null byte.
The raw file data follows. Following the raw file data is the next file
entry, or EOF.
When used on the wire protocol, an additional line indicating protocol
@@ -195,33 +194,46 @@ def generatev1(repo):
lock.release()
repo.ui.debug('%d files, %d bytes to transfer\n' %
(len(entries), total_bytes))
- yield '%d %d\n' % (len(entries), total_bytes)
svfs = repo.svfs
oldaudit = svfs.mustaudit
debugflag = repo.ui.debugflag
svfs.mustaudit = False
- try:
- for name, size in entries:
- if debugflag:
- repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
- # partially encode name over the wire for backwards compat
- yield '%s\0%d\n' % (store.encodedir(name), size)
- if size <= 65536:
- fp = svfs(name)
- try:
- data = fp.read(size)
- finally:
- fp.close()
- yield data
- else:
- for chunk in util.filechunkiter(svfs(name), limit=size):
- yield chunk
- finally:
- svfs.mustaudit = oldaudit
+ def emitrevlogdata():
+ try:
+ for name, size in entries:
+ if debugflag:
+ repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
+ # partially encode name over the wire for backwards compat
+ yield '%s\0%d\n' % (store.encodedir(name), size)
+ if size <= 65536:
+ fp = svfs(name)
+ try:
+ data = fp.read(size)
+ finally:
+ fp.close()
+ yield data
+ else:
+ for chunk in util.filechunkiter(svfs(name), limit=size):
+ yield chunk
+ finally:
+ svfs.mustaudit = oldaudit
+
+ return len(entries), total_bytes, emitrevlogdata()
+
+def generatev1wireproto(repo):
+ """Emit content for version 1 of streaming clone suitable for the wire.
+
+ This is the data output from ``generatev1()`` with a header line
+ indicating file count and byte size.
+ """
+ filecount, bytecount, it = generatev1(repo)
+ yield '%d %d\n' % (filecount, bytecount)
+ for chunk in it:
+ yield chunk
def consumev1(repo, fp, filecount, bytecount):
"""Apply the contents from version 1 of a streaming clone file handle.
diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
--- a/mercurial/wireproto.py
+++ b/mercurial/wireproto.py
@@ -717,9 +717,9 @@ def stream(repo, proto):
try:
# LockError may be raised before the first result is yielded. Don't
# emit output until we're sure we got the lock successfully.
- it = streamclone.generatev1(repo)
+ it = streamclone.generatev1wireproto(repo)
return streamres(getstream(it))
except error.LockError:
return '2\n'
More information about the Mercurial-devel
mailing list