robustcheckout: factor network failure handling into own function (
bug 1317594); r?glob
We're going to introduce another consumer. Let's make the code easier
to call.
MozReview-Commit-ID: 6Zx59um4XiX
--- a/hgext/robustcheckout/__init__.py
+++ b/hgext/robustcheckout/__init__.py
@@ -221,51 +221,54 @@ def _docheckout(ui, url, dest, upstream,
ui.warn('(attempting checkout from beginning)\n')
return callself()
raise
# At this point we either have an existing working directory using
# shared, pooled storage or we have nothing.
+ def handlenetworkfailure():
+ if networkattempts[0] >= networkattemptlimit:
+ raise error.Abort('reached maximum number of network attempts; '
+ 'giving up\n')
+
+ ui.warn('(retrying after network failure on attempt %d of %d)\n' %
+ (networkattempts[0], networkattemptlimit))
+
+ # Do a backoff on retries to mitigate the thundering herd
+ # problem. This is an exponential backoff with a multipler
+ # plus random jitter thrown in for good measure.
+ # With the default settings, backoffs will be:
+ # 1) 2.5 - 6.5
+ # 2) 5.5 - 9.5
+ # 3) 11.5 - 15.5
+ backoff = (2 ** networkattempts[0] - 1) * 1.5
+ jittermin = ui.configint('robustcheckout', 'retryjittermin', 1000)
+ jittermax = ui.configint('robustcheckout', 'retryjittermax', 5000)
+ backoff += float(random.randint(jittermin, jittermax)) / 1000.0
+ ui.warn('(waiting %.2fs before retry)\n' % backoff)
+ time.sleep(backoff)
+
+ networkattempts[0] += 1
+
def handlepullabort(e):
"""Handle an error.Abort raised during a pull.
Returns True if caller should call ``callself()`` to retry.
"""
if e.args[0] == _('repository is unrelated'):
ui.warn('(repository is unrelated; deleting)\n')
destvfs.rmtree(forcibly=True)
return True
elif e.args[0].startswith(_('stream ended unexpectedly')):
ui.warn('%s\n' % e.args[0])
- if networkattempts[0] < networkattemptlimit:
- ui.warn('(retrying after network failure on attempt %d of %d)\n' %
- (networkattempts[0], networkattemptlimit))
-
- # Do a backoff on retries to mitigate the thundering herd
- # problem. This is an exponential backoff with a multipler
- # plus random jitter thrown in for good measure.
- # With the default settings, backoffs will be:
- # 1) 2.5 - 6.5
- # 2) 5.5 - 9.5
- # 3) 11.5 - 15.5
- backoff = (2 ** networkattempts[0] - 1) * 1.5
- jittermin = ui.configint('robustcheckout', 'retryjittermin', 1000)
- jittermax = ui.configint('robustcheckout', 'retryjittermax', 5000)
- backoff += float(random.randint(jittermin, jittermax)) / 1000.0
- ui.warn('(waiting %.2fs before retry)\n' % backoff)
- time.sleep(backoff)
-
- networkattempts[0] += 1
-
- return True
- else:
- raise error.Abort('reached maximum number of network attempts; '
- 'giving up\n')
+ # Will raise if failure limit reached.
+ handlenetworkfailure()
+ return True
return False
created = False
if not destvfs.exists():
# Ensure parent directories of destination exist.
# Mercurial 3.8 removed ensuredirs and made makedirs race safe.