Skip to main content
Temporal Java SDK

Code walkthrough

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

This video walks through the example application from the previous lesson, showing how the Worker, the Temporal Cluster, and the Client Application drive a Workflow Execution from start to finish - and how Temporal recovers from a Worker crash and a transient Activity failure.

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.

This example starts the Worker by invoking the main method inside the class shown here, which launches a new process.

The code in this method begins by creating a WorkflowServiceStubs instance, which represents a connection to a Temporal Cluster that's running locally. Next, it uses this instance to create a Temporal Client that can communicate with that cluster. Finally, it uses the Client to create a WorkerFactory that can be used to create one or more Workers.

Next, it uses that factory to create a new Worker instance, which we refer to as a "Worker Entity." The string passed to the method here is the name of the Task Queue on the Temporal Cluster that the Worker Entity will poll.

A Worker will only execute Tasks for Workflow and Activity Types that have been registered with it.

The lines highlighted here perform that registration, using references to classes that implement 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 Entity 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, which matches the value used to initialize the Worker Entity. It also specifies a user-defined Workflow ID, the Workflow Type, and the input data in JSON format.

An alternative is to start it from code within your own application by using a Temporal Client to call the Workflow Method, in this case the greetSomeone method, 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 and WorkflowExecutionStarted will be 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 method from the Workflow Definition.

It continues by running code within this method. In this example, the first few statements configure timeout options for the Activities.

The code highlighted here requests execution of the first Activity for this Workflow, greetInSpanish, the result of which will be assigned to the spanishGreeting variable. Since the result won't be available until the greetInSpanish Activity returns a value, this call will block until the Activity Execution is complete.

A couple of important things also happen as a result of the request for execution of the greetInSpanish Activity. Since the Worker can't make further progress on the Workflow until the Activity Execution concludes, it notifies the Cluster that the current Workflow Task is complete. In response, the Cluster adds a new Event to the 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 method corresponding to the Activity Definition for the greetInSpanish Activity.

The Worker then runs the code within the method. In this case, the Activity calls the utility method, 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 method returns, the 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 method for the second Activity.

As before, it then runs the code within the method, 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 method to throw an exception.

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 method again, which in turn invokes the utility method 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.

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