clone: disable stream support on server side by default.
authorVadim Gelfer <vadim.gelfer@gmail.com>
Sat, 15 Jul 2006 16:06:35 -0700
changeset 2621 5a5852a417b1
parent 2620 de82749d3a71
child 2622 064aef9162cc
clone: disable stream support on server side by default. enable in hgrc like this: [server] stream=True
doc/hgrc.5.txt
mercurial/hg.py
mercurial/hgweb/hgweb_mod.py
mercurial/localrepo.py
mercurial/sshserver.py
mercurial/streamclone.py
tests/test-http
tests/test-http-proxy
tests/test-http.out
tests/test-ssh
--- a/doc/hgrc.5.txt	Sat Jul 15 16:06:05 2006 -0700
+++ b/doc/hgrc.5.txt	Sat Jul 15 16:06:35 2006 -0700
@@ -317,7 +317,7 @@
   Assigns symbolic names to repositories.  The left side is the
   symbolic name, and the right gives the directory or URL that is the
   location of the repository.  Default paths can be declared by
- setting the following entries.
+  setting the following entries.
   default;;
     Directory or URL to use when pulling if no source is specified.
     Default is set to repository from which the current repository
@@ -326,6 +326,18 @@
     Optional.  Directory or URL to use when pushing if no destination
     is specified.
 
+server::
+  Controls generic server settings.
+  stream;;
+    Whether to allow clients to clone a repo using the uncompressed
+    streaming protocol.  This transfers about 40% more data than a
+    regular clone, but uses less memory and CPU on both server and
+    client.  Over a LAN (100Mbps or better) or a very fast WAN, an
+    uncompressed streaming clone is a lot faster (~10x) than a regular
+    clone.  Over most WAN connections (anything slower than about
+    6Mbps), uncompressed streaming is slower, because of the extra
+    data transfer overhead.  Default is False.
+
 ui::
   User interface controls.
   debug;;
--- a/mercurial/hg.py	Sat Jul 15 16:06:05 2006 -0700
+++ b/mercurial/hg.py	Sat Jul 15 16:06:35 2006 -0700
@@ -97,7 +97,8 @@
 
     pull: always pull from source repository, even in local case
 
-    stream: stream from repository (fast over LAN, slow over WAN)
+    stream: stream raw data uncompressed from repository (fast over
+    LAN, slow over WAN)
 
     rev: revision to clone up to (implies pull=True)
 
--- a/mercurial/hgweb/hgweb_mod.py	Sat Jul 15 16:06:05 2006 -0700
+++ b/mercurial/hgweb/hgweb_mod.py	Sat Jul 15 16:06:35 2006 -0700
@@ -860,7 +860,10 @@
                   or self.t("error", error="%r not found" % fname))
 
     def do_capabilities(self, req):
-        resp = 'unbundle stream=%d' % (self.repo.revlogversion,)
+        caps = ['unbundle']
+        if self.repo.ui.configbool('server', 'stream'):
+            caps.append('stream=%d' % self.repo.revlogversion)
+        resp = ' '.join(caps)
         req.httphdr("application/mercurial-0.1", length=len(resp))
         req.write(resp)
 
--- a/mercurial/localrepo.py	Sat Jul 15 16:06:05 2006 -0700
+++ b/mercurial/localrepo.py	Sat Jul 15 16:06:35 2006 -0700
@@ -2204,8 +2204,11 @@
             return 1
 
     def stream_in(self, remote):
+        fp = remote.stream_out()
+        resp = int(fp.readline())
+        if resp != 0:
+            raise util.Abort(_('operation forbidden by server'))
         self.ui.status(_('streaming all changes\n'))
-        fp = remote.stream_out()
         total_files, total_bytes = map(int, fp.readline().split(' ', 1))
         self.ui.status(_('%d files to transfer, %s of data\n') %
                        (total_files, util.bytecount(total_bytes)))
@@ -2230,14 +2233,15 @@
 
         keyword arguments:
         heads: list of revs to clone (forces use of pull)
-        pull: force use of pull, even if remote can stream'''
+        stream: use streaming clone if possible'''
 
-        # now, all clients that can stream can read repo formats
-        # supported by all servers that can stream.
+        # now, all clients that can request uncompressed clones can
+        # read repo formats supported by all servers that can serve
+        # them.
 
         # if revlog format changes, client will have to check version
-        # and format flags on "stream" capability, and stream only if
-        # compatible.
+        # and format flags on "stream" capability, and use
+        # uncompressed only if compatible.
 
         if stream and not heads and remote.capable('stream'):
             return self.stream_in(remote)
--- a/mercurial/sshserver.py	Sat Jul 15 16:06:05 2006 -0700
+++ b/mercurial/sshserver.py	Sat Jul 15 16:06:35 2006 -0700
@@ -60,8 +60,10 @@
         capabilities: space separated list of tokens
         '''
 
-        r = "capabilities: unbundle stream=%d\n" % (self.repo.revlogversion,)
-        self.respond(r)
+        caps = ['unbundle']
+        if self.ui.configbool('server', 'stream'):
+            caps.append('stream=%d' % self.repo.revlogversion)
+        self.respond("capabilities: %s\n" % (' '.join(caps),))
 
     def do_lock(self):
         '''DEPRECATED - allowing remote client to lock repo is not safe'''
--- a/mercurial/streamclone.py	Sat Jul 15 16:06:05 2006 -0700
+++ b/mercurial/streamclone.py	Sat Jul 15 16:06:35 2006 -0700
@@ -59,6 +59,13 @@
 def stream_out(repo, fileobj):
     '''stream out all metadata files in repository.
     writes to file-like object, must support write() and optional flush().'''
+
+    if not repo.ui.configbool('server', 'stream'):
+        fileobj.write('1\n')
+        return
+
+    fileobj.write('0\n')
+
     # get consistent snapshot of repo. lock during scan so lock not
     # needed while we stream, and commits can happen.
     lock = repo.lock()
--- a/tests/test-http	Sat Jul 15 16:06:05 2006 -0700
+++ b/tests/test-http	Sat Jul 15 16:06:35 2006 -0700
@@ -1,23 +1,23 @@
 #!/bin/sh
 
-mkdir test
+hg init test
 cd test
 echo foo>foo
-hg init
-hg addremove
-hg commit -m 1
-hg verify
-hg serve -p 20059 -d --pid-file=hg.pid
-cat hg.pid >> $DAEMON_PIDS
+hg commit -A -d '0 0' -m 1
+hg --config server.stream=True serve -p 20059 -d --pid-file=hg1.pid
+cat hg1.pid >> $DAEMON_PIDS
+hg serve -p 20060 -d --pid-file=hg2.pid
+cat hg2.pid >> $DAEMON_PIDS
 cd ..
 
 echo % clone via stream
-http_proxy= hg clone --stream http://localhost:20059/ copy 2>&1 | \
+http_proxy= hg clone --uncompressed http://localhost:20059/ copy 2>&1 | \
   sed -e 's/[0-9][0-9.]*/XXX/g'
 cd copy
 hg verify
 
-cd ..
+echo % try to clone via stream, should use pull instead
+http_proxy= hg clone --uncompressed http://localhost:20060/ copy2
 
 echo % clone via pull
 http_proxy= hg clone http://localhost:20059/ copy-pull
--- a/tests/test-http-proxy	Sat Jul 15 16:06:05 2006 -0700
+++ b/tests/test-http-proxy	Sat Jul 15 16:06:35 2006 -0700
@@ -4,7 +4,7 @@
 cd a
 echo a > a
 hg ci -Ama -d '1123456789 0'
-hg serve -p 20059 -d --pid-file=hg.pid
+hg --config server.stream=True serve -p 20059 -d --pid-file=hg.pid
 cat hg.pid >> $DAEMON_PIDS
 
 cd ..
@@ -14,7 +14,7 @@
 sleep 2
 
 echo %% url for proxy, stream
-http_proxy=http://localhost:20060/ hg --config http_proxy.always=True clone --stream http://localhost:20059/ b | \
+http_proxy=http://localhost:20060/ hg --config http_proxy.always=True clone --uncompressed http://localhost:20059/ b | \
   sed -e 's/[0-9][0-9.]*/XXX/g'
 cd b
 hg verify
--- a/tests/test-http.out	Sat Jul 15 16:06:05 2006 -0700
+++ b/tests/test-http.out	Sat Jul 15 16:06:35 2006 -0700
@@ -1,10 +1,4 @@
-(the addremove command is deprecated; use add and remove --after instead)
 adding foo
-checking changesets
-checking manifests
-crosschecking files in changesets and manifests
-checking files
-1 files, 1 changesets, 1 total revisions
 % clone via stream
 streaming all changes
 XXX files to transfer, XXX bytes of data
@@ -15,6 +9,13 @@
 crosschecking files in changesets and manifests
 checking files
 1 files, 1 changesets, 1 total revisions
+% try to clone via stream, should use pull instead
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 % clone via pull
 requesting all changes
 adding changesets
--- a/tests/test-ssh	Sat Jul 15 16:06:05 2006 -0700
+++ b/tests/test-ssh	Sat Jul 15 16:06:35 2006 -0700
@@ -27,11 +27,13 @@
 cd remote
 echo this > foo
 hg ci -A -m "init" -d "1000000 0" foo
+echo '[server]' > .hg/hgrc
+echo 'stream = True' >> .hg/hgrc
 
 cd ..
 
 echo "# clone remote via stream"
-hg clone -e ./dummyssh --stream ssh://user@dummy/remote local-stream 2>&1 | \
+hg clone -e ./dummyssh --uncompressed ssh://user@dummy/remote local-stream 2>&1 | \
   sed -e 's/[0-9][0-9.]*/XXX/g'
 cd local-stream
 hg verify