Skip to main content
Temporal Go SDK

Code walkthrough

Free previewTemporal 101Go
  1. About this example
  2. Code walkthrough

Watch a step-by-step walkthrough of the example application as a Workflow Execution progresses. Pay attention to the Event History on the right side of the screen - new events appear as the Worker, the Temporal Cluster, and the Client interact.

Video

Transcript

Video Transcript

As you learned, the Worker executes your Workflow and Activity code, so a Workflow Execution cannot progress unless at least one Worker is running. Launching the Worker creates a new process. Since this example is written in Go, a program begins by locating the main package and running the main function.

This function first creates a Temporal client.

Next, it creates a new Worker Entity with that client, the name of the Task Queue, and options for configuring its behavior. This example uses the default options.

A Worker can execute Workflow and Activity Tasks for types that are registered with it. The highlighted lines include references to function names in the Workflow and Activity Definitions.

Running the Worker Entity opens a long-lasting connection to the Temporal Cluster, which it uses to continuously poll for new tasks. Although the Worker is running, the Workflow is not, so the task queue is empty and the Worker has nothing to do.

One way to start the Workflow is with the temporal command-line tool. This example specifies the name of the Worker's task queue, a user-defined Workflow ID, the Workflow Type, and the input data.

An alternative is to start it from code within your own application by using a Temporal client to call the ExecuteWorkflow function with your input.

Regardless of how you start the Workflow, the behavior will be the same: the Temporal Cluster records a new Event into the Event History of this Workflow Execution. WorkflowExecutionStarted is always the first Event.

As I continue with my explanation, pay attention to the Event History shown on the right. Additional events will begin appearing below this one as Workflow Execution progresses. I won't mention all of them, but I highlight them in yellow when they first appear so they're easier to spot.

The Temporal Cluster adds a Workflow Task to the Task Queue and records another event, WorkflowTaskScheduled, into the Event History. Its name follows a pattern: when a new Task is added to the queue, the name ends with "Scheduled."

Since the Worker Process has capacity to do some processing work, it accepts this new Task. This results in a new Event, one whose name also follows a pattern. When a Worker dequeues a Task, the Cluster generates an event whose name ends with "Started."

The Worker Process begins the Workflow Task by invoking the function from the Workflow Definition. It continues by running code within this function. In this example, the first few statements configure timeout options for the Activities.

The Workflow code highlighted here declares a variable that will receive the output of our first Activity and then requests execution of that Activity: GreetInSpanish. Since ExecuteActivity returns a Future, and this example invokes a Get function on that, it will block until the Activity Execution completes, at which point we can access the output if the execution was successful or the error if it was not.

A few important things happen as a result of the ExecuteActivity call. The Worker can't make further progress on the Workflow until the Activity Execution concludes, so it notifies the Cluster that the current Workflow Task is complete. In response, the Cluster adds a new Event to history. The Worker also sends a command to the cluster requesting it to schedule an Activity Task.

The Temporal Cluster creates an Activity Task and adds it to the Task Queue, resulting in a new Event.

Since the Worker Process has capacity to perform additional work, it accepts the Activity Task.

The Worker Entity now invokes the function corresponding to the Activity Definition for the GreetInSpanish Activity.

The Worker then runs the code within the function. In this case, the Activity calls the utility function, which in turn issues a request to the microservice.

This request was successful and the service responds by providing a customized greeting in Spanish.

When the Activity function returns, Worker notifies the cluster that the Activity Task is complete, resulting in a new Event.

In response, the Temporal Cluster queues a new Workflow Task and logs another Event.

When the Worker accepts this new Task, the Temporal Cluster adds a WorkflowTaskStarted Event to the History.

The Worker continues where it left off by executing the next statement in the Workflow Definition.

It is now time to execute the second Activity, so the Worker notifies the Temporal Cluster that the current Workflow Task is complete and sends a Command to schedule an Activity Task.

The Temporal Cluster queues an Activity Task for the second Activity and logs an ActivityTaskScheduled Event to the history. Let's take a moment to look at a failure scenario. What happens if the Worker crashes; for example, because it ran out of memory?

You can recover from this by restarting the Worker or launching a new Worker on a different machine. In either case, Temporal will automatically recreate the state of the Workflow up to the point of failure, so progress will continue on from there, as if the Worker never crashed at all.

Activities that completed successfully before the crash won't be executed again; instead, Temporal reuses the values returned by their previous executions.

When the Worker accepts the Activity Task. The Temporal Cluster adds ActivityTaskStarted to the Event History.

The Worker now invokes the function for the second Activity. As before, it then runs the code within the function, which uses the utility method to call a microservice.

But what if that microservice went offline just before the request? In this case, the request would fail, ultimately causing the Activity function to return an error.

The default behavior in Temporal is for a failed Activity to be automatically retried, with a short delay, until it succeeds or is canceled. You can customize this behavior with a Retry Policy.

Through a retry, the Worker invokes the Activity function again, which in turn invokes the utility function and calls out to the microservice.

For this example, let's assume that the service outage was an intermittent failure, so the request made during the retry is successful.

Since the service is now back online, it responds to our latest request and provides the requested farewell message.

When the function returns, the Worker notifies the Temporal Cluster that the Activity Task is complete.

There are still a few lines of the Workflow code that haven't been run yet, so the Temporal Cluster adds a new Workflow Task to the queue.

When the Worker accepts this new Task, the Temporal Cluster adds a WorkflowTaskStarted Event to the history. The Worker continues where it left off, executing the remaining statements in the Workflow Definition.

Once this function returns, the Workflow Task is complete.

Since the Workflow function returned, Workflow Execution is now complete, and the Cluster adds the final event to its history.

The Worker continues polling for new Tasks, but there is no more work related to this Workflow Execution.

The client application, which has been awaiting the result of the Workflow Execution because it's blocked on the Get call, will now receive that value.

The cluster provides the result to the application, which can process it however it wishes.

And now you've seen what happens during a Workflow Execution.

You've finished the free preview

Continue on TalentLMS to unlock the rest of Temporal 101 - including quizzes, the certificate, and the deeper material on Workflow Execution, Event History, failure handling, and more.

Get notified when we launch new educational content

New courses, tutorials, and learning resources - straight to your inbox.

Subscribe
Feedback