зеркало из https://github.com/mozilla/bugbug.git
Pull running 'hg pull' instead of using hglib to benefit from Mercurial's default transaction rollback (#1715)
Currently we use hglib, so when we send SIGTERM to the process which is doing the pull, the process is terminated without error handling and the repository is left in a bad state. Instead, by using 'hg pull', we benefit from Mercurial's handling of SIGTERM: transaction rollback. Might help with #1673
This commit is contained in:
Родитель
256003a052
Коммит
f375d686f4
|
@ -10,7 +10,6 @@ import itertools
|
|||
import json
|
||||
import logging
|
||||
import math
|
||||
import multiprocessing
|
||||
import os
|
||||
import pickle
|
||||
import shelve
|
||||
|
@ -1092,12 +1091,12 @@ def clean(hg, repo_dir):
|
|||
raise
|
||||
|
||||
|
||||
def _run_hg_cmd(repo_dir, cmd, *args, **kwargs):
|
||||
def _build_hg_cmd(cmd, *args, **kwargs):
|
||||
cmd = hglib.util.cmdbuilder(cmd, *args, **kwargs,)
|
||||
|
||||
cmd.insert(0, hglib.HGPATH)
|
||||
|
||||
subprocess.run(cmd, cwd=repo_dir, check=True)
|
||||
return cmd
|
||||
|
||||
|
||||
def clone(
|
||||
|
@ -1126,8 +1125,7 @@ def clone(
|
|||
if "abort: repository" not in str(e) and "not found" not in str(e):
|
||||
raise
|
||||
|
||||
_run_hg_cmd(
|
||||
None,
|
||||
cmd = _build_hg_cmd(
|
||||
"robustcheckout",
|
||||
url,
|
||||
repo_dir,
|
||||
|
@ -1137,6 +1135,7 @@ def clone(
|
|||
branch=b"tip",
|
||||
noupdate=not update,
|
||||
)
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
logger.info(f"{repo_dir} cloned")
|
||||
|
||||
|
@ -1144,27 +1143,27 @@ def clone(
|
|||
def pull(repo_dir: str, branch: str, revision: str) -> None:
|
||||
"""Pull a revision from a branch of a remote repository into a local repository"""
|
||||
|
||||
def do_pull() -> None:
|
||||
with hglib.open(repo_dir) as hg:
|
||||
hg.pull(
|
||||
source=f"https://hg.mozilla.org/{branch}/".encode("ascii"),
|
||||
rev=revision.encode("ascii"),
|
||||
)
|
||||
|
||||
@tenacity.retry(
|
||||
stop=tenacity.stop_after_attempt(3),
|
||||
reraise=True,
|
||||
after=tenacity.after_log(logger, logging.DEBUG),
|
||||
)
|
||||
def trigger_pull() -> None:
|
||||
p = multiprocessing.Process(target=do_pull)
|
||||
p.start()
|
||||
p.join(60 * 3)
|
||||
cmd = _build_hg_cmd(
|
||||
"pull",
|
||||
f"https://hg.mozilla.org/{branch}/".encode("ascii"),
|
||||
r=revision.encode("ascii"),
|
||||
debug=True,
|
||||
)
|
||||
|
||||
if p.is_alive():
|
||||
p = subprocess.Popen(cmd, cwd=repo_dir)
|
||||
|
||||
try:
|
||||
p.wait(timeout=180)
|
||||
except subprocess.TimeoutExpired:
|
||||
p.terminate()
|
||||
p.join()
|
||||
raise Exception(f"Timed out while pulling from {branch} after 3 minutes")
|
||||
p.wait()
|
||||
raise
|
||||
|
||||
trigger_pull()
|
||||
|
||||
|
|
|
@ -229,14 +229,16 @@ def mock_repo(tmpdir: py.path.local, monkeypatch: MonkeyPatch) -> Tuple[str, str
|
|||
# Allow using the local code analysis server.
|
||||
responses.add_passthru("http://127.0.0.1")
|
||||
|
||||
orig_hgclient_pull = hglib.client.hgclient.pull
|
||||
orig_hgutil_cmdbuilder = hglib.util.cmdbuilder
|
||||
|
||||
def hglib_pull(hgclient, source=None, rev=None, update=False):
|
||||
orig_hgclient_pull(
|
||||
hgclient, source=str(remote_dir).encode("ascii"), rev=rev, update=update
|
||||
)
|
||||
def hglib_cmdbuilder(name, *args, **kwargs):
|
||||
if name == "pull":
|
||||
args = list(args)
|
||||
args[0] = str(remote_dir).encode("ascii")
|
||||
|
||||
monkeypatch.setattr(hglib.client.hgclient, "pull", hglib_pull)
|
||||
return orig_hgutil_cmdbuilder(name, *args, **kwargs)
|
||||
|
||||
monkeypatch.setattr(hglib.util, "cmdbuilder", hglib_cmdbuilder)
|
||||
|
||||
return local_dir, remote_dir
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче