Patchwork [6,of,6,clone,bundles] clonebundles: advertise clone bundles feature to clients

login
register
mail settings
Submitter Gregory Szorc
Date Oct. 14, 2015, 6:07 p.m.
Message ID <2aaae4e1134db787e6fd.1444846078@gps-mbp.local>
Download mbox | patch
Permalink /patch/11073/
State Accepted
Headers show

Comments

Gregory Szorc - Oct. 14, 2015, 6:07 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1444845953 25200
#      Wed Oct 14 11:05:53 2015 -0700
# Node ID 2aaae4e1134db787e6fdc41829b17451750a2d4d
# Parent  69474173bfb98339226a29c0ba132adb7619626a
clonebundles: advertise clone bundles feature to clients

Server operators that have enabled clone bundles probably want clients
to use it. This patch introduces a feature that will insert a bundle2
"output" part that advertises the existence of the clone bundles
feature to clients that aren't using it.

The server uses the "cbattempted" argument to "getbundle" to determine
whether a client supports clone bundles and to avoid sending the message
to clients that failed the clone bundle for whatever reason.
Augie Fackler - Oct. 15, 2015, 1:47 p.m.
On Wed, Oct 14, 2015 at 11:07:58AM -0700, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@gmail.com>
> # Date 1444845953 25200
> #      Wed Oct 14 11:05:53 2015 -0700
> # Node ID 2aaae4e1134db787e6fdc41829b17451750a2d4d
> # Parent  69474173bfb98339226a29c0ba132adb7619626a
> clonebundles: advertise clone bundles feature to clients

Queued these, thanks.

>
> Server operators that have enabled clone bundles probably want clients
> to use it. This patch introduces a feature that will insert a bundle2
> "output" part that advertises the existence of the clone bundles
> feature to clients that aren't using it.
>
> The server uses the "cbattempted" argument to "getbundle" to determine
> whether a client supports clone bundles and to avoid sending the message
> to clients that failed the clone bundle for whatever reason.
>
> diff --git a/hgext/clonebundles.py b/hgext/clonebundles.py
> --- a/hgext/clonebundles.py
> +++ b/hgext/clonebundles.py
> @@ -63,9 +63,12 @@ REQUIRESNI
>
>     Value should be "true".
>  """
>
> +from mercurial.i18n import _
> +from mercurial.node import nullid
>  from mercurial import (
> +    exchange,
>      extensions,
>      wireproto,
>  )
>
> @@ -93,6 +96,45 @@ def bundles(repo, proto):
>      the closest data center given the client's IP address.
>      """
>      return repo.opener.tryread('clonebundles.manifest')
>
> +@exchange.getbundle2partsgenerator('clonebundlesadvertise', 0)
> +def advertiseclonebundlespart(bundler, repo, source, bundlecaps=None,
> +                              b2caps=None, heads=None, common=None,
> +                              cbattempted=None, **kwargs):
> +    """Inserts an output part to advertise clone bundles availability."""
> +    # Allow server operators to disable this behavior.
> +    # # experimental config: ui.clonebundleadvertise
> +    if not repo.ui.configbool('ui', 'clonebundleadvertise', True):
> +        return
> +
> +    # Only advertise if a manifest is present.
> +    if not repo.opener.exists('clonebundles.manifest'):
> +        return
> +
> +    # And when changegroup data is requested.
> +    if not kwargs.get('cg', True):
> +        return
> +
> +    # And when the client supports clone bundles.
> +    if cbattempted is None:
> +        return
> +
> +    # And when the client didn't attempt a clone bundle as part of this pull.
> +    if cbattempted:
> +        return
> +
> +    # And when a full clone is requested.
> +    # Note: client should not send "cbattempted" for regular pulls. This check
> +    # is defense in depth.
> +    if common and common != [nullid]:
> +        return
> +
> +    msg = _('this server supports the experimental "clone bundles" feature '
> +            'that should enable faster and more reliable cloning\n'
> +            'help test it by setting the "experimental.clonebundles" config '
> +            'flag to "true"')
> +
> +    bundler.newpart('output', data=msg)
> +
>  def extsetup(ui):
>      extensions.wrapfunction(wireproto, '_capabilities', capabilities)
> diff --git a/tests/test-clonebundles.t b/tests/test-clonebundles.t
> --- a/tests/test-clonebundles.t
> +++ b/tests/test-clonebundles.t
> @@ -63,8 +63,19 @@ Empty manifest file results in retrieval
>    adding manifests
>    adding file changes
>    added 2 changesets with 2 changes to 2 files
>
> +Server advertises presence of feature to client requesting full clone
> +
> +  $ hg --config experimental.clonebundles=false clone -U http://localhost:$HGPORT advertise-on-clone
> +  requesting all changes
> +  remote: this server supports the experimental "clone bundles" feature that should enable faster and more reliable cloning
> +  remote: help test it by setting the "experimental.clonebundles" config flag to "true"
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 2 changesets with 2 changes to 2 files
> +
>  Manifest file with invalid URL aborts
>
>    $ echo 'http://does.not.exist/bundle.hg' > server/.hg/clonebundles.manifest
>    $ hg clone http://localhost:$HGPORT 404-url
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> https://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff --git a/hgext/clonebundles.py b/hgext/clonebundles.py
--- a/hgext/clonebundles.py
+++ b/hgext/clonebundles.py
@@ -63,9 +63,12 @@  REQUIRESNI
 
    Value should be "true".
 """
 
+from mercurial.i18n import _
+from mercurial.node import nullid
 from mercurial import (
+    exchange,
     extensions,
     wireproto,
 )
 
@@ -93,6 +96,45 @@  def bundles(repo, proto):
     the closest data center given the client's IP address.
     """
     return repo.opener.tryread('clonebundles.manifest')
 
+@exchange.getbundle2partsgenerator('clonebundlesadvertise', 0)
+def advertiseclonebundlespart(bundler, repo, source, bundlecaps=None,
+                              b2caps=None, heads=None, common=None,
+                              cbattempted=None, **kwargs):
+    """Inserts an output part to advertise clone bundles availability."""
+    # Allow server operators to disable this behavior.
+    # # experimental config: ui.clonebundleadvertise
+    if not repo.ui.configbool('ui', 'clonebundleadvertise', True):
+        return
+
+    # Only advertise if a manifest is present.
+    if not repo.opener.exists('clonebundles.manifest'):
+        return
+
+    # And when changegroup data is requested.
+    if not kwargs.get('cg', True):
+        return
+
+    # And when the client supports clone bundles.
+    if cbattempted is None:
+        return
+
+    # And when the client didn't attempt a clone bundle as part of this pull.
+    if cbattempted:
+        return
+
+    # And when a full clone is requested.
+    # Note: client should not send "cbattempted" for regular pulls. This check
+    # is defense in depth.
+    if common and common != [nullid]:
+        return
+
+    msg = _('this server supports the experimental "clone bundles" feature '
+            'that should enable faster and more reliable cloning\n'
+            'help test it by setting the "experimental.clonebundles" config '
+            'flag to "true"')
+
+    bundler.newpart('output', data=msg)
+
 def extsetup(ui):
     extensions.wrapfunction(wireproto, '_capabilities', capabilities)
diff --git a/tests/test-clonebundles.t b/tests/test-clonebundles.t
--- a/tests/test-clonebundles.t
+++ b/tests/test-clonebundles.t
@@ -63,8 +63,19 @@  Empty manifest file results in retrieval
   adding manifests
   adding file changes
   added 2 changesets with 2 changes to 2 files
 
+Server advertises presence of feature to client requesting full clone
+
+  $ hg --config experimental.clonebundles=false clone -U http://localhost:$HGPORT advertise-on-clone
+  requesting all changes
+  remote: this server supports the experimental "clone bundles" feature that should enable faster and more reliable cloning
+  remote: help test it by setting the "experimental.clonebundles" config flag to "true"
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+
 Manifest file with invalid URL aborts
 
   $ echo 'http://does.not.exist/bundle.hg' > server/.hg/clonebundles.manifest
   $ hg clone http://localhost:$HGPORT 404-url