Event-Driven Microservices with Cloud Pub/Sub and Eventarc on Cloud Run
Synchronous HTTP request-response cycles are poorly suited for heavy operations like high-definition audio generation, image resizing, and PDF rendering. Offloading long-running work to asynchronous background event consumers keeps user-facing APIs responsive.
In AustinSS Blogs, audio article reader generation (Google Cloud Text-to-Speech Journey voices) and media processing are designed around Eventarc and Cloud Pub/Sub.
1. Cloud Storage Eventarc Triggers
When an author uploads a hero banner image or media asset, a Cloud Storage google.cloud.storage.object.v1.finalized event triggers our background processing worker via Eventarc:
resource "google_eventarc_trigger" "image_processor" {
name = "trigger-image-processor"
location = "us-central1"
matching_criteria {
attribute = "type"
value = "google.cloud.storage.object.v1.finalized"
}
matching_criteria {
attribute = "bucket"
value = "austinss-blog-media-dev"
}
destination {
cloud_run_service {
service = "austinss-blog-worker"
region = "us-central1"
}
}
service_account = google_service_account.eventarc_invoker.email
}
2. Handling CloudEvents in FastAPI
Cloud Run receives events formatted as standard CloudEvents HTTP POST payloads:
from fastapi import APIRouter, Header, Request
router = APIRouter()
@router.post("/events/media-uploaded")
async def handle_media_event(
request: Request,
ce_type: str = Header(alias="ce-type"),
ce_source: str = Header(alias="ce-source"),
):
if ce_type == "google.cloud.storage.object.v1.finalized":
event_data = await request.json()
bucket = event_data["bucket"]
object_name = event_data["name"]
# Trigger background image compression or audio synthesis
return {"status": "accepted", "object": object_name}
return {"status": "ignored"}
This guarantees sub-50ms user response times while processing compute-heavy background tasks on demand.