Skip to content

Commit 81a717b

Browse files
authored
repo_synchroniser: retry all remote operations (bug 1982268) (#73)
* retry: return callback's return * repo_synchroniser: retry all remote operations (bug 1982268) Otherwise we may needlessly fail the message on transient errors.
1 parent 2fb2cb9 commit 81a717b

File tree

2 files changed

+40
-19
lines changed

2 files changed

+40
-19
lines changed

git_hg_sync/repo_synchronizer.py

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,13 @@ def fetch_all_from_remote(
5656
self, repo: Repo, remote: str, verbose: bool = False
5757
) -> None:
5858
try:
59-
self._log_git_execute(
60-
repo,
61-
["git", "-c", "cinnabar.graft=true", "fetch", "--tags", remote],
62-
verbose,
59+
retry(
60+
f"fetching changes and tags from {remote}",
61+
lambda: self._log_git_execute(
62+
repo,
63+
["git", "-c", "cinnabar.graft=true", "fetch", "--tags", remote],
64+
verbose,
65+
),
6366
)
6467

6568
except GitCommandError as exc:
@@ -68,7 +71,12 @@ def fetch_all_from_remote(
6871
raise exc
6972

7073
if remote.startswith("hg::"):
71-
self._log_git_execute(repo, ["git", "cinnabar", "fetch", "--tags"], verbose)
74+
retry(
75+
f"fetching Hg tags with cinnabar from {remote}",
76+
lambda: self._log_git_execute(
77+
repo, ["git", "cinnabar", "fetch", "--tags"], verbose
78+
),
79+
)
7280

7381
@staticmethod
7482
def _log_git_execute(repo: Repo, command: list[str], verbose: bool = False) -> None:
@@ -173,15 +181,20 @@ def sync(
173181
# If the destination branch is not present locally, but exists remotely, we
174182
# explicitly fetch it.
175183
local_branch_exists = repo.git.branch("-l", tag_branch)
176-
remote_branch_exists = repo.git.execute(
177-
[
178-
"git",
179-
"ls-remote",
180-
destination_remote,
181-
self._cinnabar_branch(tag_branch),
182-
],
183-
stdout_as_string=True,
184+
remote_branch_exists = retry(
185+
"checking if tag branch already exists remotely",
186+
partial(
187+
repo.git.execute,
188+
[
189+
"git",
190+
"ls-remote",
191+
destination_remote,
192+
self._cinnabar_branch(tag_branch),
193+
],
194+
stdout_as_string=True,
195+
),
184196
)
197+
185198
if not local_branch_exists and remote_branch_exists:
186199
retry(
187200
f"fetching existing tag branch from {destination_remote}",
@@ -247,9 +260,13 @@ def sync(
247260
push_args = [destination_remote, ref]
248261
# Force-push the branch if it doesn't exist on the remote yet.
249262
# This is necessary to create new branches, more specifically for tags.
250-
if not repo.git.execute(
251-
["git", "ls-remote", destination_remote, ref.split(":")[1]],
252-
stdout_as_string=True,
263+
if not retry(
264+
"checking if destination branch needs to be created",
265+
partial(
266+
repo.git.execute,
267+
["git", "ls-remote", destination_remote, ref.split(":")[1]],
268+
stdout_as_string=True,
269+
),
253270
):
254271
push_args = ["-f"] + push_args
255272
logger.debug(f"Push arguments: {push_args}")

git_hg_sync/retry.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import time
22
from collections.abc import Callable
3+
from typing import Any
34

45
import sentry_sdk
56
from mozlog import get_proxy_logger
@@ -13,7 +14,7 @@ def retry(
1314
*,
1415
tries: int = 2,
1516
delay: float = 0.25,
16-
) -> None:
17+
) -> Any:
1718
"""Run a `callback` up to `tries` times with a `delay` between Exceptions.
1819
1920
The `callback` can be a closure built from a lambda function if needed.
@@ -42,8 +43,7 @@ def retry(
4243
logger.debug(action)
4344
for attempt in range(1, tries + 1):
4445
try:
45-
callback()
46-
break
46+
return callback()
4747
except Exception as exc:
4848
sentry_sdk.capture_exception(exc)
4949
action_text = f" {action}" if action else ""
@@ -59,3 +59,7 @@ def retry(
5959
exc_info=True,
6060
)
6161
raise
62+
63+
raise Exception(
64+
"The retryable callback should have either succeeded or raised, so we should not be here."
65+
)

0 commit comments

Comments
 (0)