From 278a30ac38f98004ed77796a14ebf040114f374b Mon Sep 17 00:00:00 2001 From: Jennifer Davis Date: Sat, 7 Nov 2026 03:37:35 +0000 Subject: [PATCH] docs(cloud_scheduler): trim sample comments Shorten the comments and two docstrings in the Cloud Scheduler samples so that each comment states one fact a reader needs, and remove comments that restate the code. The code doesn't change. --- cloud_scheduler/receiver/main.py | 27 ++++++------------- .../snippets/create_appengine_job.py | 8 ++---- .../snippets/create_http_job_oauth.py | 6 ++--- cloud_scheduler/snippets/create_job.py | 13 +++------ .../snippets/create_job_with_retry.py | 12 +++------ cloud_scheduler/snippets/create_pubsub_job.py | 6 ++--- cloud_scheduler/snippets/get_job.py | 3 +-- cloud_scheduler/snippets/list_jobs.py | 1 - cloud_scheduler/snippets/pause_job.py | 4 +-- cloud_scheduler/snippets/resume_job.py | 4 +-- cloud_scheduler/snippets/update_job.py | 9 +++---- 11 files changed, 28 insertions(+), 65 deletions(-) diff --git a/cloud_scheduler/receiver/main.py b/cloud_scheduler/receiver/main.py index 12e2fbdaa6..e31317b294 100644 --- a/cloud_scheduler/receiver/main.py +++ b/cloud_scheduler/receiver/main.py @@ -19,11 +19,8 @@ import flask import functions_framework -# Cloud Scheduler can deliver the same scheduled run more than once, sometimes -# at nearly the same time, so the function claims each run before doing its -# work. These in-memory claims last only for the life of one instance. In -# production, claim each run with a single atomic write, such as creating a -# Firestore document that fails if the document already exists. +# Duplicate deliveries of a run are skipped. Use a durable store, such as +# Firestore, across instances. claimed_runs: set[str] = set() claimed_runs_lock = threading.Lock() @@ -45,38 +42,30 @@ def process_run(job_name: str, schedule_time: str, payload: str) -> None: @functions_framework.http def handle_scheduled_run(request: flask.Request) -> tuple[str, int]: - """Handles a request that a Cloud Scheduler job sends to this function. + """Handles a Cloud Scheduler request. - Deploy the function to require authentication. Cloud Run functions then - verifies the job's OIDC token before the request reaches this - function, and only service accounts with the Cloud Run Invoker role can - call it. + Cloud Run functions verifies the job's OIDC token. """ job_name = request.headers.get("X-CloudScheduler-JobName") schedule_time = request.headers.get("X-CloudScheduler-ScheduleTime") if not job_name or not schedule_time: return "error: missing Cloud Scheduler headers", 400 - # The schedule time stays the same when Cloud Scheduler retries a run, - # so the job name and schedule time identify a single scheduled run. + # Retries keep the same schedule time, so this identifies one run. run_key = f"{job_name}/{schedule_time}" - # Check and claim the run in one step, so that two deliveries of the same - # run that arrive together can't both do the work. + # Check and claim in one step so concurrent duplicates can't both run. with claimed_runs_lock: if run_key in claimed_runs: log("Skipped duplicate run", jobName=job_name, scheduleTime=schedule_time) return "Duplicate run skipped", 200 claimed_runs.add(run_key) - # Finish the work within the job's attempt deadline. Cloud Scheduler - # treats a slow response as a failure even if the work later succeeds. + # Finish within the job's attempt deadline. try: process_run(job_name, schedule_time, request.get_data(as_text=True)) except Exception: - # Release the claim so that a retry can process the run. Re-raising - # returns HTTP 500, which tells Cloud Scheduler to retry the run - # according to the job's retry settings. + # Release the claim; the 500 response makes Cloud Scheduler retry. with claimed_runs_lock: claimed_runs.discard(run_key) raise diff --git a/cloud_scheduler/snippets/create_appengine_job.py b/cloud_scheduler/snippets/create_appengine_job.py index 2040605313..29fce124b6 100644 --- a/cloud_scheduler/snippets/create_appengine_job.py +++ b/cloud_scheduler/snippets/create_appengine_job.py @@ -30,8 +30,7 @@ def create_appengine_job(project_id: str, location_id: str, job_id: str) -> None job_id: The ID for the new job (for example, 'example-job-id'). """ client = scheduler_v1.CloudSchedulerClient() - # App Engine targets must be in the same project and region as the - # App Engine app. + # Must be the App Engine app's project and region. parent = f"projects/{project_id}/locations/{location_id}" app_engine_routing = scheduler_v1.AppEngineRouting(service="default") @@ -44,12 +43,9 @@ def create_appengine_job(project_id: str, location_id: str, job_id: str) -> None job = scheduler_v1.Job( name=f"{parent}/jobs/{job_id}", app_engine_http_target=app_engine_target, - # Runs every Monday at 09:00. UTC avoids skipped or repeated runs when - # daylight saving time starts or ends. + # Every Monday at 09:00 UTC, which has no daylight saving shifts. schedule="0 9 * * 1", time_zone="UTC", - # Cloud Scheduler reports a failure if the handler doesn't respond - # within this deadline. attempt_deadline=datetime.timedelta(minutes=5), ) request = scheduler_v1.CreateJobRequest(parent=parent, job=job) diff --git a/cloud_scheduler/snippets/create_http_job_oauth.py b/cloud_scheduler/snippets/create_http_job_oauth.py index 7cef27d08f..1e92f5d431 100644 --- a/cloud_scheduler/snippets/create_http_job_oauth.py +++ b/cloud_scheduler/snippets/create_http_job_oauth.py @@ -48,8 +48,7 @@ def create_http_job_oauth( f"/workflowTemplates/{workflow_template_id}" ) - # Use an OAuth token, not an OIDC token, when the target is a Google API - # hosted on *.googleapis.com. + # Google APIs (*.googleapis.com) need an OAuth token, not OIDC. oauth_token = scheduler_v1.OAuthToken( service_account_email=service_account_email, scope="https://www.googleapis.com/auth/cloud-platform", @@ -64,8 +63,7 @@ def create_http_job_oauth( job = scheduler_v1.Job( name=f"{parent}/jobs/{job_id}", http_target=http_target, - # Runs every Monday at 09:00. UTC avoids skipped or repeated runs when - # daylight saving time starts or ends. + # Every Monday at 09:00 UTC, which has no daylight saving shifts. schedule="0 9 * * 1", time_zone="UTC", ) diff --git a/cloud_scheduler/snippets/create_job.py b/cloud_scheduler/snippets/create_job.py index 93b293dc6d..8b8591e5b6 100644 --- a/cloud_scheduler/snippets/create_job.py +++ b/cloud_scheduler/snippets/create_job.py @@ -27,10 +27,7 @@ def create_job( service_url: str, service_account_email: str, ) -> None: - """Creates a job that calls a Cloud Run service on a schedule. - - The job authenticates with an OIDC token for a service account, so the - Cloud Run service can require authentication. + """Creates a job that calls a Cloud Run service on a schedule with an OIDC token. Args: project_id: The Google Cloud project ID (for example, 'example-project-id'). @@ -43,7 +40,7 @@ def create_job( client = scheduler_v1.CloudSchedulerClient() parent = f"projects/{project_id}/locations/{location_id}" - # Cloud Run accepts the token only if its audience matches the service URL. + # The audience must match the service URL. oidc_token = scheduler_v1.OidcToken( service_account_email=service_account_email, audience=service_url, @@ -57,12 +54,10 @@ def create_job( job = scheduler_v1.Job( name=f"{parent}/jobs/{job_id}", http_target=http_target, - # Runs every Monday at 09:00. UTC avoids skipped or repeated runs when - # daylight saving time starts or ends. + # Every Monday at 09:00 UTC, which has no daylight saving shifts. schedule="0 9 * * 1", time_zone="UTC", - # Cloud Scheduler reports a failure if the service doesn't respond - # within this deadline, so match it to the service's request timeout. + # Match the service's request timeout. attempt_deadline=datetime.timedelta(minutes=5), ) request = scheduler_v1.CreateJobRequest(parent=parent, job=job) diff --git a/cloud_scheduler/snippets/create_job_with_retry.py b/cloud_scheduler/snippets/create_job_with_retry.py index 3120cd07da..41f6356999 100644 --- a/cloud_scheduler/snippets/create_job_with_retry.py +++ b/cloud_scheduler/snippets/create_job_with_retry.py @@ -50,10 +50,8 @@ def create_job_with_retry( body=b"example-payload", oidc_token=oidc_token, ) - # Cloud Scheduler stops retrying a run when it reaches either limit: - # retry_count retries or max_retry_duration since the first attempt. - # The wait between retries starts at min_backoff_duration, doubles - # max_doublings times, and then grows linearly up to max_backoff_duration. + # Retries stop at retry_count or max_retry_duration, whichever comes first. + # Waits start at min_backoff and double up to max_backoff. retry_config = scheduler_v1.RetryConfig( retry_count=3, max_retry_duration=datetime.timedelta(hours=1), @@ -65,12 +63,10 @@ def create_job_with_retry( name=f"{parent}/jobs/{job_id}", http_target=http_target, retry_config=retry_config, - # Runs every Monday at 09:00. UTC avoids skipped or repeated runs when - # daylight saving time starts or ends. + # Every Monday at 09:00 UTC, which has no daylight saving shifts. schedule="0 9 * * 1", time_zone="UTC", - # A response that misses this deadline counts as a failed attempt and - # is retried, so match it to the service's request timeout. + # A slow response counts as a failed attempt. attempt_deadline=datetime.timedelta(minutes=5), ) request = scheduler_v1.CreateJobRequest(parent=parent, job=job) diff --git a/cloud_scheduler/snippets/create_pubsub_job.py b/cloud_scheduler/snippets/create_pubsub_job.py index 21a352f690..faae58031b 100644 --- a/cloud_scheduler/snippets/create_pubsub_job.py +++ b/cloud_scheduler/snippets/create_pubsub_job.py @@ -34,8 +34,7 @@ def create_pubsub_job( client = scheduler_v1.CloudSchedulerClient() parent = f"projects/{project_id}/locations/{location_id}" - # Cloud Scheduler publishes by using its service agent, which needs the - # Cloud Scheduler Service Agent role in the project. + # Publishes as the Cloud Scheduler service agent. pubsub_target = scheduler_v1.PubsubTarget( topic_name=f"projects/{project_id}/topics/{topic_id}", data=b"example-payload", @@ -44,8 +43,7 @@ def create_pubsub_job( job = scheduler_v1.Job( name=f"{parent}/jobs/{job_id}", pubsub_target=pubsub_target, - # Runs every Monday at 09:00. UTC avoids skipped or repeated runs when - # daylight saving time starts or ends. + # Every Monday at 09:00 UTC, which has no daylight saving shifts. schedule="0 9 * * 1", time_zone="UTC", ) diff --git a/cloud_scheduler/snippets/get_job.py b/cloud_scheduler/snippets/get_job.py index cddbeead8b..07ada99acd 100644 --- a/cloud_scheduler/snippets/get_job.py +++ b/cloud_scheduler/snippets/get_job.py @@ -47,8 +47,7 @@ def get_job(project_id: str, location_id: str, job_id: str) -> None: ) else: print(f"Resource ID: {response.name}") - # The last attempt time and status code are empty until the job runs. - # A status code of 0 means the last attempt succeeded. + # Status code 0 means the last attempt succeeded. print(f"Last Attempt Time: {response.last_attempt_time}") print(f"State: {response.state.name}") print(f"Status Code: {response.status.code}") diff --git a/cloud_scheduler/snippets/list_jobs.py b/cloud_scheduler/snippets/list_jobs.py index 990bba591a..5f86371e2f 100644 --- a/cloud_scheduler/snippets/list_jobs.py +++ b/cloud_scheduler/snippets/list_jobs.py @@ -31,7 +31,6 @@ def list_jobs(project_id: str, location_id: str) -> None: request = scheduler_v1.ListJobsRequest(parent=parent) try: - # The client fetches more pages as the loop needs them. for job in client.list_jobs(request=request): print(f"Resource ID: {job.name}") print(f"Schedule: {job.schedule}") diff --git a/cloud_scheduler/snippets/pause_job.py b/cloud_scheduler/snippets/pause_job.py index 0eb55c44e7..bc072b6d51 100644 --- a/cloud_scheduler/snippets/pause_job.py +++ b/cloud_scheduler/snippets/pause_job.py @@ -33,9 +33,7 @@ def pause_job(project_id: str, location_id: str, job_id: str) -> None: name = f"projects/{project_id}/locations/{location_id}/jobs/{job_id}" request = scheduler_v1.PauseJobRequest(name=name) - # Cloud Scheduler applies one change to a job at a time. If another change - # is still in progress, this call fails with ABORTED; retry after a few - # seconds. + # Fails with ABORTED while another change to the job is in progress. try: response = client.pause_job(request=request) except exceptions.NotFound as err: diff --git a/cloud_scheduler/snippets/resume_job.py b/cloud_scheduler/snippets/resume_job.py index 8455192a81..eca24488a9 100644 --- a/cloud_scheduler/snippets/resume_job.py +++ b/cloud_scheduler/snippets/resume_job.py @@ -33,9 +33,7 @@ def resume_job(project_id: str, location_id: str, job_id: str) -> None: name = f"projects/{project_id}/locations/{location_id}/jobs/{job_id}" request = scheduler_v1.ResumeJobRequest(name=name) - # Cloud Scheduler applies one change to a job at a time. If another change - # is still in progress, this call fails with ABORTED; retry after a few - # seconds. + # Fails with ABORTED while another change to the job is in progress. try: response = client.resume_job(request=request) except exceptions.NotFound as err: diff --git a/cloud_scheduler/snippets/update_job.py b/cloud_scheduler/snippets/update_job.py index d9632a900f..3864022ec0 100644 --- a/cloud_scheduler/snippets/update_job.py +++ b/cloud_scheduler/snippets/update_job.py @@ -31,16 +31,13 @@ def update_job(project_id: str, location_id: str, job_id: str) -> None: client = scheduler_v1.CloudSchedulerClient() name = f"projects/{project_id}/locations/{location_id}/jobs/{job_id}" - # Runs every weekday at 10:00 UTC. + # Every weekday at 10:00 UTC. job = scheduler_v1.Job(name=name, schedule="0 10 * * 1-5", time_zone="UTC") - # Only the fields in the update mask change; the job keeps its other - # settings, such as its target. + # Only fields in the update mask change. update_mask = field_mask_pb2.FieldMask(paths=["schedule", "time_zone"]) request = scheduler_v1.UpdateJobRequest(job=job, update_mask=update_mask) - # Cloud Scheduler applies one change to a job at a time. If another change - # is still in progress, this call fails with ABORTED; retry after a few - # seconds. + # Fails with ABORTED while another change to the job is in progress. try: response = client.update_job(request=request) except exceptions.NotFound as err: