Skip to content

Commit 050f0c4

Browse files
committed
Reviewing and some updates
1 parent 4bfdba9 commit 050f0c4

8 files changed

Lines changed: 51 additions & 21 deletions

File tree

core/src/main/java/io/temporal/samples/nexus_messaging/README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
This sample shows how to expose a long-running workflow's queries, updates, and signals as Nexus
22
operations. There are two self-contained examples, each in its own directory:
33

4-
| | `callerpattern/` | `ondemandpattern/` |
5-
|---|---|---|
6-
| **Pattern** | Signal an existing workflow | Create and run workflows on demand |
7-
| **Who creates the workflow?** | The handler worker starts it on boot | The caller starts it via a Nexus operation |
8-
| **Who knows the workflow ID?** | Only the handler | The caller chooses and passes it in every operation |
9-
| **Nexus service** | `NexusGreetingService` | `NexusRemoteGreetingService` |
4+
| | `callerpattern/` | `ondemandpattern/` |
5+
|---|---|--------------------------------------------------------------|
6+
| **Pattern** | Signal an existing workflow | Create and run workflows on demand, and send signals to them |
7+
| **Who creates the workflow?** | The handler worker starts it on boot | The caller starts it via a Nexus operation |
8+
| **Who knows the workflow ID?** | Only the handler | The caller chooses and passes it in every operation |
9+
| **Nexus service** | `NexusGreetingService` | `NexusRemoteGreetingService` |
1010

11-
Each directory is fully self-contained with its own `service/`, `handler/`, and caller code. The
12-
`GreetingWorkflow` and `GreetingWorkflowImpl` classes are **identical** between the two — only the
11+
Each directory is fully self-contained for clarity. The
12+
`GreetingWorkflow`, `GreetingWorkflowImpl`, `GreetingActivity` and `GreetingActivityImpl` classes are **identical** between the two — only the
1313
Nexus service interface and its implementation differ. This highlights that the same workflow can be
1414
exposed through Nexus in different ways depending on whether the caller needs lifecycle control.
1515

core/src/main/java/io/temporal/samples/nexus_messaging/callerpattern/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ The handler worker starts a single `GreetingWorkflow` with a fixed workflow ID.
44
`NexusGreetingServiceImpl` holds that ID and routes every Nexus operation to it. The caller's
55
inputs contain only business data — no workflow IDs.
66

7+
Refer to the on demand pattern examples and you will see how to expand this example to not just a single fixed workflow ID - the NexusGreetingServiceImpl simply needs to be able to map something from the inputs to a Workflow ID. For example if the workflow ID is a user ID with a prefix, then if the Nexus inputs include a User ID, then Nexus can simple prepend the same string to get the desired workflow ID.
8+
79
The caller workflow:
810
1. Queries for supported languages (`getLanguages` — backed by a `@QueryMethod`)
911
2. Changes the language to Arabic (`setLanguage` — backed by an `@UpdateMethod` that calls an activity)

core/src/main/java/io/temporal/samples/nexus_messaging/callerpattern/caller/CallerStarter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public static void main(String[] args) {
2424
.setTaskQueue(CallerWorker.TASK_QUEUE)
2525
.build());
2626

27+
// Launch the worker, passing in an identifier which the Nexus service will use
28+
// to find the matching workflow (See NexusGreetingServiceImpl::getWorkflowId)
2729
List<String> log = workflow.run("user-1");
2830
log.forEach(System.out::println);
2931
}

core/src/main/java/io/temporal/samples/nexus_messaging/callerpattern/caller/CallerWorkflowImpl.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,30 @@ public class CallerWorkflowImpl implements CallerWorkflow {
2929

3030
@Override
3131
public List<String> run(String userId) {
32+
33+
// Messages in the log array are passed back to the caller who will then log them to report what
34+
// is happening.
35+
// The same message is also logged for demo purposes, so that things are visible in the caller
36+
// workflow output.
3237
List<String> log = new ArrayList<>();
3338

34-
// 👉 Call a Nexus operation backed by a query against the entity workflow.
39+
// Call a Nexus operation backed by a query against the entity workflow.
40+
// The workflow must already be running on the handler, otherwise you will
41+
// get an error saying the workflow has already terminated.
3542
NexusGreetingService.GetLanguagesOutput languagesOutput =
3643
greetingService.getLanguages(new NexusGreetingService.GetLanguagesInput(false, userId));
3744
log.add("Supported languages: " + languagesOutput.getLanguages());
3845
logger.info("Supported languages: {}", languagesOutput.getLanguages());
3946

40-
// 👉 Call a Nexus operation backed by an update against the entity workflow.
47+
// Following are examples for each of the three messaging types -
48+
// update, query, then signal.
49+
50+
// Call a Nexus operation backed by an update against the entity workflow.
4151
Language previousLanguage =
4252
greetingService.setLanguage(
4353
new NexusGreetingService.SetLanguageInput(Language.ARABIC, userId));
4454

45-
// 👉 Call a Nexus operation backed by a query to confirm the language change.
55+
// Call a Nexus operation backed by a query to confirm the language change.
4656
Language currentLanguage =
4757
greetingService.getLanguage(new NexusGreetingService.GetLanguageInput(userId));
4858
if (currentLanguage != Language.ARABIC) {
@@ -53,7 +63,7 @@ public List<String> run(String userId) {
5363
log.add("Language changed: " + previousLanguage.name() + " -> " + Language.ARABIC.name());
5464
logger.info("Language changed from {} to {}", previousLanguage, Language.ARABIC);
5565

56-
// 👉 Call a Nexus operation backed by a signal against the entity workflow.
66+
// Call a Nexus operation backed by a signal against the entity workflow.
5767
greetingService.approve(new NexusGreetingService.ApproveInput("caller", userId));
5868
log.add("Workflow approved");
5969
logger.info("Workflow approved");

core/src/main/java/io/temporal/samples/nexus_messaging/callerpattern/handler/HandlerWorker.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,13 @@ public static void main(String[] args) throws InterruptedException {
2424
service, WorkflowClientOptions.newBuilder().setNamespace(NAMESPACE).build());
2525

2626
// Start the long-running entity workflow that backs the Nexus service, if not already running.
27-
// The workflow ID is derived from the user ID using the same prefix as
28-
// NexusGreetingServiceImpl.
27+
// Create a workflow ID derived from the given user ID.
28+
// This would be for a process that would create a workflow for each UserID,
29+
// if you had a single long running workflow for all users then you could
30+
// remove all the USER_IDs from the inputs and just make everything refer
31+
// to a single workflow ID.
2932
String workflowId = NexusGreetingServiceImpl.getWorkflowId(USER_ID);
33+
3034
GreetingWorkflow greetingWorkflow =
3135
client.newWorkflowStub(
3236
GreetingWorkflow.class,

core/src/main/java/io/temporal/samples/nexus_messaging/callerpattern/handler/NexusGreetingServiceImpl.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ public class NexusGreetingServiceImpl {
2121

2222
static final String WORKFLOW_ID_PREFIX = "GreetingWorkflow_for_";
2323

24+
// This example assumes you might have multiple workflows, one for each user.
25+
// If you had a single workflow for all users, then you could remove the
26+
// getWorkflowId method, remove the user ID from each input, and just
27+
// use the single worflow ID in the getWorkflowStub method below.
2428
public static String getWorkflowId(String userId) {
2529
return WORKFLOW_ID_PREFIX + userId;
2630
}

core/src/main/java/io/temporal/samples/nexus_messaging/ondemandpattern/caller/CallerRemoteWorkflowImpl.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ public class CallerRemoteWorkflowImpl implements CallerRemoteWorkflow {
1515

1616
private static final Logger logger = Workflow.getLogger(CallerRemoteWorkflowImpl.class);
1717

18-
// private static final String REMOTE_WORKFLOW_ID = "nexus-messaging-remote-greeting-workflow";
18+
// This is going to create two workflows and send messages to them.
19+
// We need to have an ID to differentiate so that Nexus knows how to name
20+
// a workflow and then how to know the correct destination workflow.
21+
// So here we are just going to define two workflow IDs with different user IDs.
1922
private static final String REMOTE_WORKFLOW_ONE = "UserId One";
2023
private static final String REMOTE_WORKFLOW_TWO = "UserId Two";
2124

@@ -40,9 +43,19 @@ public class CallerRemoteWorkflowImpl implements CallerRemoteWorkflow {
4043

4144
@Override
4245
public List<String> run() {
46+
// Messages in the log array are passed back to the caller who will then log them to report what
47+
// is happening.
48+
// The same message is also logged for demo purposes, so that things are visible in the caller
49+
// workflow output.
4350
List<String> log = new ArrayList<>();
4451

45-
// 👉 Async Nexus operation — starts a workflow on the handler and returns a handle.
52+
// Each call is performed twice in this example. This assumes there are two users we want
53+
// to process. The first call starts two workflows, one for each user.
54+
// Subsequent calls perform different actions between the two users.
55+
// There are examples for each of the three messaging types -
56+
// update, query, then signal.
57+
58+
// This is an Async Nexus operation — starts a workflow on the handler and returns a handle.
4659
// Unlike the sync operations below (getLanguages, setLanguage, etc.), this does not block
4760
// until the workflow completes. It is backed by WorkflowRunOperation on the handler side.
4861
NexusOperationHandle<String> handleOne =

core/src/main/java/io/temporal/samples/nexus_messaging/ondemandpattern/handler/NexusRemoteGreetingServiceImpl.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@ private GreetingWorkflow getWorkflowStub(String workflowId) {
3030

3131
// Starts a new GreetingWorkflow with the caller-specified workflow ID. This is an async
3232
// Nexus operation backed by WorkflowRunOperation.
33-
//
34-
// fromWorkflowHandle (rather than fromWorkflowMethod) is used here because the Nexus operation
35-
// input (RunFromRemoteInput) differs from the workflow method parameters — run() takes no args.
36-
// The input is consumed to set the workflow ID on the stub; the workflow itself is invoked
37-
// with no arguments via the ::run method reference.
3833
@OperationImpl
3934
public OperationHandler<NexusRemoteGreetingService.RunFromRemoteInput, String> runFromRemote() {
4035
return WorkflowRunOperation.fromWorkflowHandle(

0 commit comments

Comments
 (0)