Google Cloud
Google Cloud Run is the Google Cloud service that Text Control names for applications built with TX Text Control .NET Server. It runs the container image from Dockerfile without a cluster of your own, and it suits document processing and the Document Viewer well, because both answer each request on its own. The Document Editor needs more attention: its WebSocket connection counts as a request and is subject to the request timeout of the service.
What Cloud Run Expects From the Image
- An x86_64 image. Cloud Run supports the Linux x86_64 ABI format, which matches the
linux-x64libraries of the Core engine. Build the image on an x86_64 machine or with a build service; an image built on an ARM machine doesn't run. - A container that listens on the port Cloud Run sets. Cloud Run routes traffic to port 8080 by default and passes the port in the
PORTenvironment variable. The .NET container images listen on 8080, so the image from the Dockerfile page fits. - A file system in memory. What the container writes uses the memory of the instance and is gone when the instance stops. The Fonts folder and the Document Editor backend are part of the image, so nothing has to be written; store generated documents in a bucket or a database.
Deploy the Image
Push the image to Artifact Registry and deploy it:
gcloud run deploy myapp LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/myapp:1.0.0
For an application with the Document Editor, set the request timeout and session affinity as well:
gcloud run services update myapp =3600
Size memory and CPU for the sessions an instance is to hold, with --memory and --cpu. Document Editor Architecture gives Text Control's guidance of 50 to 150 MB per editing session, on top of what the application itself needs.
The Document Editor on Cloud Run
WebSockets work on Cloud Run without configuration, but the platform treats them as HTTP requests. That has three consequences for editing sessions:
- The request timeout limits a connection. It's 5 minutes by default and can be raised to 60 minutes, which is also the longest a WebSocket connection of an editor can stay open. When the timeout ends the connection, the editor tries to reconnect, as The Life of an Editing Session describes.
- Session affinity is best effort. Cloud Run routes a client's requests to the same instance with a cookie, but the affinity breaks when the instance is terminated or reaches its maximum concurrency or CPU utilization. A reconnect that lands on another instance fails, because that instance's backend doesn't know the connection ID, and the unsaved changes are lost. Save documents regularly, as Scaling Containers describes.
- An instance with an open connection stays active. Cloud Run considers an instance with an open WebSocket connection active, allocates CPU to it and bills it per instance. Minimum instances require this billing model as well.
Cloud Run accepts up to 1,000 concurrent connections per container. An editor opens two WebSocket connections while it initializes, so plan the maximum concurrency of the service below what the memory of an instance allows. Google also advises against HTTP/2 end-to-end for WebSocket applications.
The Document Viewer and Document Processing
Requests of the Document Viewer carry their document with them, and endpoints that create or merge documents with ServerTextControl keep nothing between requests. Both scale with the default settings of Cloud Run, need no session affinity and work with the default, request-based billing. A service that only processes documents is therefore a good fit for Cloud Run, and Text Control's recommendation to separate document processing from the editor, described in Scaling Beyond One Instance, matches this model.
When an Instance Stops
Cloud Run sends SIGTERM to the containers of an instance and ends it 10 seconds later with SIGKILL. In those 10 seconds, ASP.NET Core shuts down, and the application stops the Document Editor backend and the worker processes with the documents of all open editors.
Licensing
Each running instance needs its own runtime license. In deployments whose number of instances changes with the load, the unlimited runtime license covers them all. See Runtime Licenses and OEM / Unlimited Runtime.
Google Kubernetes Engine
For the same image in a Google Kubernetes Engine cluster, the manifests and the settings for session affinity are the ones in Kubernetes.
Next Steps
- Dockerfile: build the image that Cloud Run runs.
- Scaling Containers: what an editing session needs from a load balancer.
- Kubernetes: the same image in a cluster.
- CI/CD: build and push the image in a pipeline.