Skip to main content
Temporal .NET SDK

Code walkthrough

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

Video

Transcript

Video transcript

In this video, you will see how a Temporal Workflow Execution works by examining the code from the farewell-workflow exercise.

As you have learned, a Worker executes your Workflow and Activity code, so a Workflow Execution cannot progress unless at least one Worker is running.

Take a look at the code for a Worker. This is the Program.cs file in the Worker subdirectory, and I'll go section-by-section through the code to explain what is happening.

At the top of the file, there are some using statements that import dependencies required for this program. The first two imports are the Client and Worker from the Temporal .NET SDK. The third import is TemporalioFarewell.Workflow, a custom namespace containing Workflow and Activity definitions specific to this application.

Next, we will create a Client that connects to the local Temporal Server, which is on localhost:7233, in the default namespace. We will create an instance of TranslateActivities, making the Activities available for use in the Worker. Next, we create a new Worker Entity with that Client and the name of the Task Queue, farewell-workflow.

A Worker can execute Workflow and Activity Tasks for types that are registered with it. The highlighted lines include references to the Workflow and Activity Definitions. When you launch the Worker with the command dotnet run --project Worker, you create a new Worker process with a Worker entity and a Temporal Client which opens a long-lasting connection to the Temporal Service, 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 the Workflow from code within your own application by using a Temporal Client to call the ExecuteWorkflowAsync with your input. To run the Workflow, you will use the Client. This is the Program.cs file in the Client directory. First, you create a new Client that will communicate with the Temporal Service. Then, you start your Workflow from code within your own application by calling client.ExecuteWorkflowAsync with your input, in this case the greeting Workflow. You also specify the arguments to pass to your Workflow, in this example the name argument, the name of the Task Queue, and a unique identifier for this Workflow. When you run this code with the command dotnet run --project Client, the Temporal Service 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 the 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. You can also find these events for each Workflow Execution in the Temporal UI.

The Temporal Service 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: WorkflowTaskStarted. When a Worker dequeues a Task and accepts it, this results in a new Event that ends with "Started."

The Worker process starts by registering GreetingWorkflow, allowing it to handle workflow tasks associated with this Workflow Definition. It continues by running the code within this Workflow Definition.

Back to the Client code: client.ExecuteWorkflowAsync. A few important things happen as a result of the executing the greeting workflow. The Worker can't make further progress on the Workflow until the Activity Execution concludes, so it notifies the Service that the current Workflow Task is complete.

In response, the Service adds a new Event to the history. The Worker also sends a command to the Service requesting it to schedule an Activity Task. The Temporal Service 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 GetSpanishGreeting Activity. The Worker then runs the code within the function. In this case, the Activity 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, the Worker notifies the Service that the Activity Task is complete, resulting in a new Event. In response, the Temporal Service queues a new Workflow Task and logs another Event. When the Worker accepts this new Task, the Temporal Service 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 Service that the current Workflow Task is complete and sends a Command to schedule an Activity Task. The Temporal Service 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 Service 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 calls 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 call 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 Service 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 Service adds a new Workflow Task to the queue. When the Worker accepts this new Task, the Temporal Service 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 Service 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, will now receive that value. The Service 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