diff --git a/src/apify_client/_resource_clients/_resource_client.py b/src/apify_client/_resource_clients/_resource_client.py index 258c743b..a4451c7c 100644 --- a/src/apify_client/_resource_clients/_resource_client.py +++ b/src/apify_client/_resource_clients/_resource_client.py @@ -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: @@ -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 @@ -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 @@ -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: @@ -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 @@ -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