Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 22 additions & 12 deletions src/apify_client/_resource_clients/_resource_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,8 @@ def _wait_for_finish(
Raises:
ApifyApiError: If API returns errors other than 404.
"""
now = datetime.now(UTC)
deadline = (now + wait_duration) if wait_duration is not None else None
not_found_deadline = now + DEFAULT_WAIT_WHEN_JOB_NOT_EXIST
deadline = (datetime.now(UTC) + wait_duration) if wait_duration is not None else None
not_found_deadline: datetime | None = None
actor_job: dict = {}

while True:
Expand All @@ -317,6 +316,9 @@ def _wait_for_finish(
actor_job_response = ActorJobResponse.model_validate(result)
actor_job = actor_job_response.data.model_dump()

# Reset the not-found streak so a later transient 404 gets its own grace window.
not_found_deadline = None

is_terminal = actor_job_response.data.status in TERMINAL_STATUSES
is_timed_out = deadline is not None and datetime.now(UTC) >= deadline

Expand All @@ -326,9 +328,12 @@ def _wait_for_finish(
except ApifyApiError as exc:
catch_not_found_or_throw(exc)

# If there are still not found errors after DEFAULT_WAIT_WHEN_JOB_NOT_EXIST, we give up
# and return None. In such case, the requested record probably really doesn't exist.
if datetime.now(UTC) > not_found_deadline:
now = datetime.now(UTC)
if deadline is not None and now >= deadline:
return None
if not_found_deadline is None:
not_found_deadline = now + DEFAULT_WAIT_WHEN_JOB_NOT_EXIST
elif now > not_found_deadline:
return None

# It might take some time for database replicas to get up-to-date so sleep a bit before retrying
Expand Down Expand Up @@ -474,9 +479,8 @@ async def _wait_for_finish(
Raises:
ApifyApiError: If API returns errors other than 404.
"""
now = datetime.now(UTC)
deadline = (now + wait_duration) if wait_duration is not None else None
not_found_deadline = now + DEFAULT_WAIT_WHEN_JOB_NOT_EXIST
deadline = (datetime.now(UTC) + wait_duration) if wait_duration is not None else None
not_found_deadline: datetime | None = None
actor_job: dict = {}

while True:
Expand All @@ -497,6 +501,9 @@ async def _wait_for_finish(
actor_job_response = ActorJobResponse.model_validate(result)
actor_job = actor_job_response.data.model_dump()

# Reset the not-found streak so a later transient 404 gets its own grace window.
not_found_deadline = None

is_terminal = actor_job_response.data.status in TERMINAL_STATUSES
is_timed_out = deadline is not None and datetime.now(UTC) >= deadline

Expand All @@ -506,9 +513,12 @@ async def _wait_for_finish(
except ApifyApiError as exc:
catch_not_found_or_throw(exc)

# If there are still not found errors after DEFAULT_WAIT_WHEN_JOB_NOT_EXIST, we give up
# and return None. In such case, the requested record probably really doesn't exist.
if datetime.now(UTC) > not_found_deadline:
now = datetime.now(UTC)
if deadline is not None and now >= deadline:
return None
if not_found_deadline is None:
not_found_deadline = now + DEFAULT_WAIT_WHEN_JOB_NOT_EXIST
elif now > not_found_deadline:
return None

# It might take some time for database replicas to get up-to-date so sleep a bit before retrying
Expand Down