mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-22 13:41:26 +00:00
vimPlugins: backoff on timeout in update.py
Updating vim-plugins recently started timing out regularly for me. It may have to do with an ISP switch on my side, but I don't think that should cause timeouts. I guess I'm probably not the only one experiencing this, so in this comment I introduce exponential backoff. Every request will be retried up to 3 times (3 seconds, 6 seconds, 12 seconds delay).
This commit is contained in:
parent
61c60bad22
commit
8c757f4dc9
|
@ -21,7 +21,7 @@ import xml.etree.ElementTree as ET
|
|||
from datetime import datetime
|
||||
from multiprocessing.dummy import Pool
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Tuple, Union, Any
|
||||
from typing import Dict, List, Optional, Tuple, Union, Any, Callable
|
||||
from urllib.parse import urljoin, urlparse
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
|
@ -33,6 +33,42 @@ ROOT = Path(__file__).parent
|
|||
DEFAULT_IN = ROOT.joinpath("vim-plugin-names")
|
||||
DEFAULT_OUT = ROOT.joinpath("generated.nix")
|
||||
|
||||
import time
|
||||
from functools import wraps
|
||||
|
||||
|
||||
def retry(ExceptionToCheck: Any, tries: int = 4, delay: float = 3, backoff: float = 2):
|
||||
"""Retry calling the decorated function using an exponential backoff.
|
||||
|
||||
http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
|
||||
original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry
|
||||
(BSD licensed)
|
||||
|
||||
:param ExceptionToCheck: the exception on which to retry
|
||||
:param tries: number of times to try (not retry) before giving up
|
||||
:param delay: initial delay between retries in seconds
|
||||
:param backoff: backoff multiplier e.g. value of 2 will double the delay
|
||||
each retry
|
||||
"""
|
||||
|
||||
def deco_retry(f: Callable) -> Callable:
|
||||
@wraps(f)
|
||||
def f_retry(*args: Any, **kwargs: Any) -> Any:
|
||||
mtries, mdelay = tries, delay
|
||||
while mtries > 1:
|
||||
try:
|
||||
return f(*args, **kwargs)
|
||||
except ExceptionToCheck as e:
|
||||
print(f"{str(e)}, Retrying in {mdelay} seconds...")
|
||||
time.sleep(mdelay)
|
||||
mtries -= 1
|
||||
mdelay *= backoff
|
||||
return f(*args, **kwargs)
|
||||
|
||||
return f_retry # true decorator
|
||||
|
||||
return deco_retry
|
||||
|
||||
|
||||
class Repo:
|
||||
def __init__(self, owner: str, name: str) -> None:
|
||||
|
@ -45,9 +81,12 @@ class Repo:
|
|||
def __repr__(self) -> str:
|
||||
return f"Repo({self.owner}, {self.name})"
|
||||
|
||||
@retry(urllib.error.URLError, tries=4, delay=3, backoff=2)
|
||||
def has_submodules(self) -> bool:
|
||||
try:
|
||||
urllib.request.urlopen(self.url("blob/master/.gitmodules")).close()
|
||||
urllib.request.urlopen(
|
||||
self.url("blob/master/.gitmodules"), timeout=10
|
||||
).close()
|
||||
except urllib.error.HTTPError as e:
|
||||
if e.code == 404:
|
||||
return False
|
||||
|
@ -55,8 +94,9 @@ class Repo:
|
|||
raise
|
||||
return True
|
||||
|
||||
@retry(urllib.error.URLError, tries=4, delay=3, backoff=2)
|
||||
def latest_commit(self) -> Tuple[str, datetime]:
|
||||
with urllib.request.urlopen(self.url("commits/master.atom")) as req:
|
||||
with urllib.request.urlopen(self.url("commits/master.atom"), timeout=10) as req:
|
||||
xml = req.read()
|
||||
root = ET.fromstring(xml)
|
||||
latest_entry = root.find(ATOM_ENTRY)
|
||||
|
|
Loading…
Reference in a new issue