Patchwork D9449: phabricator: introduce a `phabricator.retry` option

login
register
mail settings
Submitter phabricator
Date Nov. 28, 2020, 8:04 p.m.
Message ID <differential-rev-PHID-DREV-tj7x5dgcoj2njsdzm2gk-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47727/
State Superseded
Headers show

Comments

phabricator - Nov. 28, 2020, 8:04 p.m.
marmoute created this revision.
Herald added subscribers: mercurial-patches, Kwan.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  For the past 2 days, my connection to phab.mercurial-scm.org became extremely
  poor. In practice this mean that any conduit call has a fairly high change to
  hang and die. Giving the amount of call done by the phabricator extension, it
  means the when I am lucky I can get 1 or 2 Diff to update after a few try, but
  anything sizeable doesn't have any hope to get through.
  
  This changesets introduce a new option for the fabricator extension to try retry
  failed command itself. So that I can get Diff through.
  
  As you can guess, this changeset managed to reach Phabricator thanks to itself.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D9449

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS




To: marmoute, #hg-reviewers
Cc: Kwan, mercurial-patches, mercurial-devel

Patch

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -35,6 +35,13 @@ 
     # the internal library.
     curlcmd = curl --connect-timeout 2 --retry 3 --silent
 
+    # retry failed command N time (default 0). Useful when using the extension
+    # over flakly connection.
+    #
+    # We wait `retry.interval` between each retry (default 1)
+    retry = 3
+    retry.interval = 10
+
     [auth]
     example.schemes = https
     example.prefix = phab.example.com
@@ -53,6 +60,7 @@ 
 import mimetypes
 import operator
 import re
+import time
 
 from mercurial.node import bin, nullid, short
 from mercurial.i18n import _
@@ -136,6 +144,16 @@ 
 )
 eh.configitem(
     b'phabricator',
+    b'retry',
+    default=0,
+)
+eh.configitem(
+    b'phabricator',
+    b'retry.interval',
+    default=1,
+)
+eh.configitem(
+    b'phabricator',
     b'url',
     default=None,
 )
@@ -400,8 +418,20 @@ 
     else:
         urlopener = urlmod.opener(ui, authinfo)
         request = util.urlreq.request(pycompat.strurl(url), data=data)
-        with contextlib.closing(urlopener.open(request)) as rsp:
-            body = rsp.read()
+        max_try = ui.configint(b'phabricator', b'retry') + 1
+        for try_count in range(max_try):
+            try:
+                with contextlib.closing(urlopener.open(request)) as rsp:
+                    body = rsp.read()
+                break
+            except util.urlerr.URLError as err:
+                ui.debug(
+                    b'Conduit Request failed (try %d/%d: %r\n'
+                    % (try_count + 1, max_try, err)
+                )
+                # failing request might come from overloaded server
+                retry_interval = ui.configint(b'phabricator', b'retry.interval')
+                time.sleep(retry_interval)
     ui.debug(b'Conduit Response: %s\n' % body)
     parsed = pycompat.rapply(
         lambda x: encoding.unitolocal(x)