Skip to content

Commit 0f593c2

Browse files
authored
fix: implement retry logic for cloud function endpoint fetching (#2369)
This PR addresses intermittent failures when creating remote functions where the Cloud Function endpoint is not immediately available after the creation operation completes. Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/python-bigquery-dataframes/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [ ] Ensure the tests and linter pass - [ ] Code coverage does not decrease (if any source code was changed) - [ ] Appropriate docs were updated (if necessary) Fixes b/473903255 🦕
1 parent e1e1141 commit 0f593c2

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

bigframes/functions/_function_client.py

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,20 @@ def generate_cloud_function_code(
375375
)
376376
return entry_point
377377

378+
@google.api_core.retry.Retry(
379+
predicate=google.api_core.retry.if_exception_type(ValueError),
380+
initial=1.0,
381+
maximum=10.0,
382+
multiplier=2.0,
383+
deadline=300.0, # Wait up to 5 minutes for propagation
384+
)
385+
def _get_cloud_function_endpoint_with_retry(self, name):
386+
endpoint = self.get_cloud_function_endpoint(name)
387+
if not endpoint:
388+
# Raising ValueError triggers the retry predicate
389+
raise ValueError(f"Endpoint for {name} not yet available.")
390+
return endpoint
391+
378392
def create_cloud_function(
379393
self,
380394
def_,
@@ -516,11 +530,14 @@ def create_cloud_function(
516530
create_function_request.function = function
517531

518532
# Create the cloud function and wait for it to be ready to use
533+
endpoint = None
519534
try:
520535
operation = self._cloud_functions_client.create_function(
521536
request=create_function_request
522537
)
523-
operation.result()
538+
# operation.result() returns the Function object upon completion
539+
function_obj = operation.result()
540+
endpoint = function_obj.service_config.uri
524541

525542
# Cleanup
526543
os.remove(archive_path)
@@ -535,12 +552,14 @@ def create_cloud_function(
535552
# we created it. This error is safe to ignore.
536553
pass
537554

538-
# Fetch the endpoint of the just created function
539-
endpoint = self.get_cloud_function_endpoint(random_name)
555+
# Fetch the endpoint with retries if it wasn't returned by the operation
540556
if not endpoint:
541-
raise bf_formatting.create_exception_with_feedback_link(
542-
ValueError, "Couldn't fetch the http endpoint."
543-
)
557+
try:
558+
endpoint = self._get_cloud_function_endpoint_with_retry(random_name)
559+
except Exception as e:
560+
raise bf_formatting.create_exception_with_feedback_link(
561+
ValueError, f"Couldn't fetch the http endpoint: {e}"
562+
)
544563

545564
logger.info(
546565
f"Successfully created cloud function {random_name} with uri ({endpoint})"

0 commit comments

Comments
 (0)