# HG changeset patch # User Pierre-Yves David # Date 1583458923 -3600 # Node ID c0b8804066dcaf989d0966a71001ff71d4dad4b6 # Parent 7c6d08cd12211c15b40581ab0bd3641676f4b250 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. diff -r 7c6d08cd1221 -r c0b8804066dc CHANGELOG --- 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 ------------------- diff -r 7c6d08cd1221 -r c0b8804066dc hgext3rd/evolve/obsdiscovery.py --- 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 diff -r 7c6d08cd1221 -r c0b8804066dc hgext3rd/evolve/obsexchange.py --- 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')