Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #34 from PrefectHQ/feature/retries
Browse files Browse the repository at this point in the history
Add retries and backoff to get_directory
  • Loading branch information
gabcoyne authored Jan 22, 2024
2 parents b9fd46b + 2ef07bd commit 079b644
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
17 changes: 17 additions & 0 deletions prefect_gitlab/repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
from prefect.utilities.asyncutils import sync_compatible
from prefect.utilities.processutils import run_process
from pydantic import VERSION as PYDANTIC_VERSION
from tenacity import retry, stop_after_attempt, wait_fixed, wait_random

if PYDANTIC_VERSION.startswith("2."):
from pydantic.v1 import Field, HttpUrl, validator
Expand All @@ -60,6 +61,13 @@

from prefect_gitlab.credentials import GitLabCredentials

# Create get_directory retry settings

MAX_CLONE_ATTEMPTS = 3
CLONE_RETRY_MIN_DELAY_SECONDS = 1
CLONE_RETRY_MIN_DELAY_JITTER_SECONDS = 0
CLONE_RETRY_MAX_DELAY_JITTER_SECONDS = 3


class GitLabRepository(ReadableDeploymentStorage):
"""
Expand Down Expand Up @@ -153,6 +161,15 @@ def _get_paths(
return str(content_source), str(content_destination)

@sync_compatible
@retry(
stop=stop_after_attempt(MAX_CLONE_ATTEMPTS),
wait=wait_fixed(CLONE_RETRY_MIN_DELAY_SECONDS)
+ wait_random(
CLONE_RETRY_MIN_DELAY_JITTER_SECONDS,
CLONE_RETRY_MAX_DELAY_JITTER_SECONDS,
),
reraise=True,
)
async def get_directory(
self, from_path: Optional[str] = None, local_path: Optional[str] = None
) -> None:
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
prefect>=2.13.5
python-gitlab>=3.12.0
tenacity>=8.2.3
21 changes: 20 additions & 1 deletion tests/test_repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

import prefect_gitlab
from prefect_gitlab.credentials import GitLabCredentials
from prefect_gitlab.repositories import GitLabRepository
from prefect_gitlab.repositories import GitLabRepository # noqa: E402


class TestGitLab:
Expand Down Expand Up @@ -243,3 +243,22 @@ class p:

assert set(os.listdir(tmp_dst)) == set([sub_dir_name])
assert set(os.listdir(Path(tmp_dst) / sub_dir_name)) == child_contents

async def test_get_directory_retries(self, monkeypatch):
# Constants for the retry decorator
MAX_CLONE_ATTEMPTS = 3

# Create an instance of GitLabRepository
g = GitLabRepository(repository="https://gitlab.com/prefectHQ/prefect.git")

# Prepare a MagicMock to simulate the process call within get_directory
mock = AsyncMock()
mock.return_value = AsyncMock(returncode=1) # Simulate failure
monkeypatch.setattr(prefect_gitlab.repositories, "run_process", mock)

# Call get_directory and expect it to raise a RetryError after maximum attempts
with pytest.raises(OSError):
await g.get_directory()
print(mock.call_count)
# Verify that the function retried the expected number of times
assert mock.call_count == MAX_CLONE_ATTEMPTS

0 comments on commit 079b644

Please sign in to comment.