{"id":13542746,"url":"https://github.com/temporal-sa/temporal-cloud-run","last_synced_at":"2025-04-02T11:30:54.751Z","repository":{"id":188789477,"uuid":"675737220","full_name":"temporal-sa/temporal-cloud-run","owner":"temporal-sa","description":"Example temporal worker application deployed to Cloud Run","archived":false,"fork":false,"pushed_at":"2024-12-12T16:41:07.000Z","size":43503,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-12-12T17:40:51.670Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/temporal-sa.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-08-07T15:53:35.000Z","updated_at":"2024-12-12T16:41:11.000Z","dependencies_parsed_at":"2023-08-16T22:09:55.170Z","dependency_job_id":null,"html_url":"https://github.com/temporal-sa/temporal-cloud-run","commit_stats":null,"previous_names":["rross/temporal-cloud-run","temporal-sa/temporal-cloud-run"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/temporal-sa%2Ftemporal-cloud-run","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/temporal-sa%2Ftemporal-cloud-run/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/temporal-sa%2Ftemporal-cloud-run/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/temporal-sa%2Ftemporal-cloud-run/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/temporal-sa","download_url":"https://codeload.github.com/temporal-sa/temporal-cloud-run/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246806484,"owners_count":20837110,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T11:00:16.838Z","updated_at":"2025-04-02T11:30:54.745Z","avatar_url":"https://github.com/temporal-sa.png","language":"Java","funding_links":[],"categories":["Tools","TypeScript"],"sub_categories":[],"readme":"# Temporal on Cloud Run\n\nThis repository demonstrates how to run workers on [GCP's Cloud Run](https://cloud.google.com/run). \nCloud Run is a serverless offering making it easier to deploy and run containerized applications. \nInitially Cloud Run was only for web based applications that responds to requests. Over time Cloud Run\nhas added the ability to run jobs as well. \n\nAs awesome as Cloud Run is, there are some challenges that need to be addressed for applications that \nact as Temporal workers. One challenge is that Cloud Run is designed to run when requests are made, \nwhich provides a nice pay per use model. Unfortunately this doesn't play well with workers which long \npoll Temporal, waiting for work to process. \n\nThe workaround for this is to disable [CPU Throttling](https://cloud.google.com/run/docs/configuring/cpu-allocation#setting). In YAML this looks like this:\n\n```yaml\nspec:\n  template:\n    metadata:\n      annotations:\n        run.googleapis.com/cpu-throttling: 'false'  # we need to keep the CPU running\n```\n\nAnother challenge is that by default, an application running Cloud Run is scaled down to zero instances \nif there are no inbound web requests. This too, doesn't play well with Temporal workers.\n\nThe workaround for this is to set the [minimum number of instances](https://cloud.google.com/run/docs/configuring/min-instances#setting):\n\n```yaml\nspec:\n  template:\n    metadata:\n      annotations:\n        autoscaling.knative.dev/minScale: '1' # keep one instance available\n```\n\nCloud Run only allows one port to be publicly exposed and exposing a Temporal SDK Metrics \nendpoint externally is not a good idea. Deploy the [Open Telemetry Connector](https://cloud.google.com/run/docs/tutorials/custom-metrics-opentelemetry-sidecar) in a \n[sidecar container](https://cloud.google.com/blog/products/serverless/cloud-run-now-supports-multi-container-deployments). \nThe Open Telemetry Collector reads the Temporal SDK Metrics Prometheus scrape endpoint and can push \nthe metrics (and optionally tracing and logging) to a destination of your choice. \n\nIn this example, I chose to send the metrics to [Google Cloud Managed Prometheus](https://cloud.google.com/managed-prometheus).\nThe collector supports a wide range of other [exporters](https://opentelemetry.io/ecosystem/registry/?component=exporter) \nincluding Prometheus Remote Write Collector, Datadog, Splunk, Google Cloud Pubsub, Google Cloud Operations Collector. \nThe full list of exporters are available [here](https://opentelemetry.io/ecosystem/registry/?component=exporter).\n\n## Project Organization\n\nThe structure of this repository is laid out in the following manner\n\n* [app](app/readme.md) - Sample Java application to deploy to Cloud Run\n* [collector](collector) - Contains details for running the Open Telemetry Connector\n* [gcp-infra](gcp-infra/readme.md) - [Pulumi](https://www.pulumi.com/) project to create a new GCP project\n\n## How to Use this example\n\n* Follow the steps listed in the [gcp-infra/readme](gcp-infra/readme.md). \n* Once the application has been deployed, you can access the application.\n\n### Access via private\n\nBy default, the application is not publicly visible. To access use the following command:\n\n```shell\ngcloud beta run services proxy temporal-metrics-sample --project \u003cPROJECT_ID\u003e --region \u003cREGION\u003e\n```\nOnce the proxy is running, visit the application by navigating to [http://localhost:8080]\n\n### Make the Application Public\n\nTo access the application via its public URL, uncomment the last step in [cloudbuild.yaml](cloudbuild.yaml). \nAlternatively, you can run the following command:\n\n````shell\ngcloud run services set-iam-policy temporal-metrics-sample policy.yaml --region \u003cREGION\u003e\n````\n\nTo retrieve the public URL run the following command:\n\n````shell\ngcloud run services describe temporal-metrics-sample --region \u003cREGION\u003e --format='value(status.url)'\n````\n\n### Start the Workflow\n\nUsing the appropriate URL, (see the section above), navigate to application. You should see the following page:\n\n![Temporal Metrics Sample Application](images/TemporalAppHome.png)\n\nClick on the Start the Metrics Worfklow\n\n![Start the Workflow](images/TemporalAppStartWorkflow.png)\n\nEnter some text for the input and click the Run Workflow button. This will start the workflow. After about 30 seconds, the workflow will complete:\n\n![Completed Workflow](images/TemporalAppWorkflowComplete.png)\n\nThe application purposefully fails the activity for a few times before completing so that there are interesting metrics.\n\nStart the workflow a couple of more times to get a few more executions. \n\nOpen up the Temporal Cloud console, by navigating to [https://cloud.temporal.io](https://cloud.temporal.io) to view the progress of the workflows.\n\n### View Metrics in Google Cloud Monitoring\n\nOpen the [Metrics Explorer](https://console.cloud.google.com/monitoring/metrics-explorer) in Google Cloud Console. In \nthe Metric drop down, scroll down to Prometheus Target, Temporal and click on Prometheus/temporal_long_request_total/counter \nand click on the Apply button.\n\n![Prometheus/temporal_long_request_total/counter](images/GCPMetricRequestTotalCounter.png)\n\nNow in the time box near the upper right of the screen, click the down arrow and select Last 30 Minutes. You should see \na graph that looks similar to this one:\n\n![Request Total Counter Graph](images/GCPMetricsRequestTotalCounterGraph.png)\n\nFeel free to experiment adding additional metrics.\n\n\n## Latest Updates - 12-19-2024\n\nThe application was modified to generate a unique Workflow ID and to return the input parameter in the output \nof the workflow. Also changed was the parameter of the application from a string to a Java Object.\n\nSpring Boot and Temporal SDK versions was updated to reflect latest versions at the time. The node versions \nin the [gcp-infra](gcp-infra) file were also updated to address vulnerabilities.\n\nBuilding the container with Docker was revised since the previous version was reliant on a deprecated openjdk8 version. \nThe new version builds a JRE with only the modules being used by the application.  \n\nIn the [run-service.yaml](run-service.yaml), it was modified to add a \"date_updated\" label that is changed on \neach deployment to Cloud Run. This is because Cloud Run is declarative and will only deploy a new revision if \ncertain values change in the yaml file. Since we are rebuilding the Java application every single time (a \nbetter approach would be to pull directly from git), this effectively forces a new revision. \n\nIn the [cloudbuild.yaml](cloudbuild.yaml) file, the label is updated to the current date and time. Due to \nstrict naming rules, the format of this is \"was_YYYY-MM-DD_HH_MM_SS\"   \n\nThe [readme.md](gcp-infra/readme.md) has been updated to include some missing steps.\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftemporal-sa%2Ftemporal-cloud-run","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftemporal-sa%2Ftemporal-cloud-run","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftemporal-sa%2Ftemporal-cloud-run/lists"}