obsexchange: fallback to simpler request for dumb http server
If the http server cannot accept many arguments, avoid sending too large
requests (at the cost of more data exchanged).
A better solution would be to aggregate contiguous range, but this is a question
for later.
--- a/CHANGELOG Fri Mar 06 02:46:51 2020 +0100
+++ b/CHANGELOG Fri Mar 06 02:42:03 2020 +0100
@@ -1,6 +1,11 @@
Changelog
=========
+9.3.0 - in progress
+-------------------
+
+ * obsexchange: avoid sending too large request to http server
+
9.3.0 -- 2020-03-04
-------------------
--- a/hgext3rd/evolve/obsdiscovery.py Fri Mar 06 02:46:51 2020 +0100
+++ b/hgext3rd/evolve/obsdiscovery.py Fri Mar 06 02:42:03 2020 +0100
@@ -866,6 +866,12 @@
% len(revs))
missing = findmissingrange(repo.ui, repo, pullop.remote, revs)
boundaries[b'missing'] = missing
+ # using getattr since `limitedarguments` is missing
+ # hg <= 5.0 (69921d02daaf)
+ if getattr(pullop.remote, 'limitedarguments', False):
+ # prepare for a possible fallback to common
+ common = repo.set("heads(only(%ld, %ln))", revs, missing)
+ boundaries[b'common'] = [c.node() for c in common]
else:
boundaries[b'common'] = [node.nullid]
return boundaries
--- a/hgext3rd/evolve/obsexchange.py Fri Mar 06 02:46:51 2020 +0100
+++ b/hgext3rd/evolve/obsexchange.py Fri Mar 06 02:42:03 2020 +0100
@@ -54,6 +54,18 @@
gboptsmap[b'evo_obscommon'] = b'nodes'
gboptsmap[b'evo_missing_nodes'] = b'nodes'
+ARGUMENTS_LIMIT = 200
+
+OVERFLOW_MSG = """obsmarkers differ for %d common nodes
+|
+| This might be too much for the remote HTTP server that doesn't accept
+| arguments through POST request. (config: experimental.httppostargs=yes)
+|
+| Falling back to a less efficient fetching method.
+|
+| More efficient fetching method is possible and will be used in the future.
+"""
+
@eh.wrapfunction(exchange, '_pullbundle2extraprepare')
def _addobscommontob2pull(orig, pullop, kwargs):
ret = orig(pullop, kwargs)
@@ -61,13 +73,22 @@
if (b'obsmarkers' in kwargs
and pullop.remote.capable(b'_evoext_getbundle_obscommon')):
boundaries = obsdiscovery.buildpullobsmarkersboundaries(pullop)
+ use_common = True
if b'missing' in boundaries:
+ use_common = False
missing = boundaries[b'missing']
- if missing:
- obsexcmsg(ui, b'request obsmarkers for %d common nodes\n'
- % len(missing))
- kwargs[b'evo_missing_nodes'] = missing
- elif b'common' in boundaries:
+ # using getattr since `limitedarguments` is missing
+ # hg <= 5.0 (69921d02daaf)
+ limitedarguments = getattr(pullop.remote, 'limitedarguments', False)
+ if limitedarguments and len(missing) > ARGUMENTS_LIMIT:
+ obsexcmsg(ui, OVERFLOW_MSG % len(missing))
+ use_common = True
+ else:
+ if missing:
+ obsexcmsg(ui, b'request obsmarkers for %d common nodes\n'
+ % len(missing))
+ kwargs[b'evo_missing_nodes'] = missing
+ if use_common and b'common' in boundaries:
common = boundaries[b'common']
if common != pullop.common:
obsexcmsg(ui, b'request obsmarkers for some common nodes\n')