Lokasi ngalangkungan proxy:   [ UP ]  
[Ngawartoskeun bug]   [Panyetelan cookie]                
Skip to content
This repository was archived by the owner on Mar 6, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
remove use of private attributes
  • Loading branch information
tswast committed Feb 20, 2025
commit 0e2d2a95ec324495b32bfa36dedacd809b04a2e7
36 changes: 11 additions & 25 deletions google/cloud/bigquery/_job_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,16 @@ def do_query():
# have pretty high confidence that by retrying the 404, we'll
# (hopefully) eventually recover the job.
# https://github.com/googleapis/python-bigquery/issues/2134
#
# Allow users who want to completely disable retries to
# continue to do so by setting retry to None.
get_job_retry = retry
if retry is not None:
get_job_retry = retry.with_predicate(
lambda exc: isinstance(exc, core_exceptions.NotFound)
# Reference the original retry to avoid recursion.
or retry._predicate(exc)
# TODO(tswast): Amend the user's retry object with allowing
# 404 to retry when there's a public way to do so.
# https://github.com/googleapis/python-api-core/issues/796
get_job_retry = (
google.cloud.bigquery.retry._DEFAULT_GET_JOB_CONFLICT_RETRY
)

query_job = client.get_job(
Expand All @@ -169,28 +173,10 @@ def do_query():
else:
return query_job

# Allow users who want to completely disable retries to
# continue to do so by setting job_retry to None.
if job_retry is not None:

def do_query_predicate(exc) -> bool:
if isinstance(exc, core_exceptions.RetryError):
exc = exc.cause

# Per https://github.com/googleapis/python-bigquery/issues/2134, sometimes
# we get a 404 error. In this case, if we get this far, assume that the job
# doesn't actually exist and try again. We can't add 404 to the default
# job_retry because that happens for errors like "this table does not
# exist", which probably won't resolve with a retry.
if isinstance(exc, core_exceptions.NotFound):
message = exc.message
# Don't try to retry table/dataset not found, just job not found.
# The URL contains jobs, so use whitespace to disambiguate.
return message is not None and " job" in message.lower()

# Reference the original job_retry to avoid recursion.
return job_retry._predicate(exc)

do_query_retry = job_retry.with_predicate(do_query_predicate)
do_query = do_query_retry(do_query)
do_query = google.cloud.bigquery.retry._DEFAULT_QUERY_JOB_INSERT_RETRY(do_query)

future = do_query()

Expand Down
51 changes: 51 additions & 0 deletions google/cloud/bigquery/retry.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,28 @@ def _should_retry(exc):
pass ``retry=bigquery.DEFAULT_RETRY.with_deadline(30)``.
"""


def _should_retry_get_job_conflict(exc):
"""Predicate for determining when to retry a jobs.get call after a conflict error.

Sometimes we get a 404 after a Conflict. In this case, we
have pretty high confidence that by retrying the 404, we'll
(hopefully) eventually recover the job.
https://github.com/googleapis/python-bigquery/issues/2134

Note: we may be able to extend this to user-specified predicates
after https://github.com/googleapis/python-api-core/issues/796
to tweak existing Retry object predicates.
"""
return isinstance(exc, exceptions.NotFound) or _should_retry(exc)


_DEFAULT_GET_JOB_CONFLICT_RETRY = retry.Retry(
predicate=_should_retry_get_job_conflict, deadline=_DEFAULT_RETRY_DEADLINE
)
"""Private, may be removed in future."""


# Note: Take care when updating DEFAULT_TIMEOUT to anything but None. We
# briefly had a default timeout, but even setting it at more than twice the
# theoretical server-side default timeout of 2 minutes was not enough for
Expand Down Expand Up @@ -142,6 +164,35 @@ def _job_should_retry(exc):
The default job retry object.
"""


def _query_job_insert_should_retry(exc):
# Per https://github.com/googleapis/python-bigquery/issues/2134, sometimes
# we get a 404 error. In this case, if we get this far, assume that the job
# doesn't actually exist and try again. We can't add 404 to the default
# job_retry because that happens for errors like "this table does not
# exist", which probably won't resolve with a retry.

if isinstance(exc, exceptions.RetryError):
exc = exc.cause

if isinstance(exc, exceptions.NotFound):
message = exc.message
# Don't try to retry table/dataset not found, just job not found.
# The URL contains jobs, so use whitespace to disambiguate.
return message is not None and " job" in message.lower()

return _job_should_retry(exc)


_DEFAULT_QUERY_JOB_INSERT_RETRY = retry.Retry(
predicate=_query_job_insert_should_retry,
# jobs.insert doesn't wait for the job to complete, so we don't need the
# long _DEFAULT_JOB_DEADLINE for this part.
deadline=_DEFAULT_RETRY_DEADLINE,
)
"""Private, may be removed in future."""


DEFAULT_GET_JOB_TIMEOUT = 128
"""
Default timeout for Client.get_job().
Expand Down