Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Nexus Cancellation

This sample shows how to cancel a Nexus operation from a caller workflow.
This sample shows how to cancel a Nexus operation from a caller workflow and specify a cancellation type. In this sample we will show using the `WAIT_REQUESTED` cancellation type, which allows the caller to return after the handler workflow has received the requested to be cancelled, but does not wait for the handler workflow to finish processing the cancellation request.

To run this sample, set up your environment following the instructions in the main [Nexus Sample](../nexus/README.md).

Expand Down Expand Up @@ -29,8 +29,19 @@ Next, in separate terminal windows:

### Output

which should result in:
which should result in on the caller side:
```
INFO i.t.s.n.caller.CallerStarter - Started workflow workflowId: 326732dd-a2b1-4de7-9ddd-dcee4f9f0229 runId: d580499f-79d5-461d-bd49-6248b4e522ae
INFO i.t.s.n.caller.CallerStarter - Workflow result: Hallo Nexus 👋
14:33:52.810 i.t.s.n.caller.CallerStarter - Started workflow workflowId: 87e97bf0-ca8a-4ae6-a9dc-ae97e5c0ac41 runId: 01976b36-a524-71a1-b848-8eb385fec2c3
14:33:54.250 i.t.s.n.caller.CallerStarter - Workflow result: Hallo Nexus 👋
```

on the handler side:

```
14:33:54.177 INFO i.t.s.n.h.HelloHandlerWorkflowImpl - HelloHandlerWorkflow was cancelled successfully.
14:33:56.167 INFO i.t.s.n.h.HelloHandlerWorkflowImpl - HelloHandlerWorkflow was cancelled successfully.
14:33:57.172 INFO i.t.s.n.h.HelloHandlerWorkflowImpl - HelloHandlerWorkflow was cancelled successfully.
14:33:57.176 INFO i.t.s.n.h.HelloHandlerWorkflowImpl - HelloHandlerWorkflow was cancelled successfully.
```

Notice the timing, the caller workflow returned before the handler workflow was cancelled. This is because of the use of `WAIT_REQUESTED` as the cancellation type in the Nexus operation. This means the caller didn't have to wait for the handler workflow to finish, but still guarantees the handler workflow will receive the cancellation request.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ public class HelloCallerWorkflowImpl implements HelloCallerWorkflow {
.setOperationOptions(
NexusOperationOptions.newBuilder()
.setScheduleToCloseTimeout(Duration.ofSeconds(10))
// Set the cancellation type to WAIT_REQUESTED. This means that the caller
// will wait for the cancellation request to be received by the handler before
// proceeding with the cancellation.
//
// By default, the caller would wait until the operation is completed.
.setCancellationType(NexusOperationCancellationType.WAIT_REQUESTED)
.build())
.build());

Expand Down Expand Up @@ -55,10 +61,12 @@ public String hello(String message) {
// Trigger cancellation of all uncompleted nexus operations invocations within the cancellation
// scope
scope.cancel();
// Optionally, wait for all nexus operations to complete
// Wait for all nexus operations to receive a cancellation request before
// proceeding.
//
// Note: Once the workflow completes any pending cancellation requests are dropped by the
// server.
// server. In general, it is a good practice to wait for all cancellation requests to be
// processed before completing the workflow.
for (Promise<NexusService.HelloOutput> promise : results) {
try {
promise.get();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,42 @@
package io.temporal.samples.nexuscancellation.handler;

import io.temporal.failure.ApplicationFailure;
import io.temporal.failure.CanceledFailure;
import io.temporal.samples.nexus.handler.HelloHandlerWorkflow;
import io.temporal.samples.nexus.service.NexusService;
import io.temporal.workflow.Workflow;
import java.time.Duration;
import org.slf4j.Logger;

public class HelloHandlerWorkflowImpl implements HelloHandlerWorkflow {
public static final Logger log = Workflow.getLogger(HelloHandlerWorkflowImpl.class);

@Override
public NexusService.HelloOutput hello(NexusService.HelloInput input) {
// Sleep for a random duration to simulate some work
Workflow.sleep(Duration.ofSeconds(Workflow.newRandom().nextInt(5)));
switch (input.getLanguage()) {
case EN:
return new NexusService.HelloOutput("Hello " + input.getName() + " 👋");
case FR:
return new NexusService.HelloOutput("Bonjour " + input.getName() + " 👋");
case DE:
return new NexusService.HelloOutput("Hallo " + input.getName() + " 👋");
case ES:
return new NexusService.HelloOutput("¡Hola! " + input.getName() + " 👋");
case TR:
return new NexusService.HelloOutput("Merhaba " + input.getName() + " 👋");
try {
Workflow.sleep(Duration.ofSeconds(Workflow.newRandom().nextInt(5)));
switch (input.getLanguage()) {
case EN:
return new NexusService.HelloOutput("Hello " + input.getName() + " 👋");
case FR:
return new NexusService.HelloOutput("Bonjour " + input.getName() + " 👋");
case DE:
return new NexusService.HelloOutput("Hallo " + input.getName() + " 👋");
case ES:
return new NexusService.HelloOutput("¡Hola! " + input.getName() + " 👋");
case TR:
return new NexusService.HelloOutput("Merhaba " + input.getName() + " 👋");
}
throw ApplicationFailure.newFailure(
"Unsupported language: " + input.getLanguage(), "UNSUPPORTED_LANGUAGE");
} catch (CanceledFailure e) {
// Simulate some work after cancellation is requested
Workflow.newDetachedCancellationScope(
() -> Workflow.sleep(Duration.ofSeconds(Workflow.newRandom().nextInt(5))))
.run();
log.info("HelloHandlerWorkflow was cancelled successfully.");
throw e;
}
throw ApplicationFailure.newFailure(
"Unsupported language: " + input.getLanguage(), "UNSUPPORTED_LANGUAGE");
}
}
Loading