Skip to content

Commit 2bdb2e4

Browse files
committed
lean example of UwS
1 parent 7e00384 commit 2bdb2e4

File tree

7 files changed

+289
-0
lines changed

7 files changed

+289
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
### Early-Return Sample
2+
3+
This sample demonstrates an early-return from a workflow.
4+
5+
By utilizing Update-with-Start, a client can start a new workflow and synchronously receive
6+
a response mid-workflow, while the workflow continues to run to completion.
7+
8+
To run the sample, start the worker:
9+
```bash
10+
./gradlew -q execute -PmainClass=io.temporal.samples.earlyreturn.EarlyReturnWorker
11+
```
12+
13+
Then, start the client:
14+
15+
```bash
16+
./gradlew -q execute -PmainClass=io.temporal.samples.earlyreturn.EarlyReturnClient
17+
```
18+
19+
* The client will start a workflow using Update-With-Start.
20+
* Update-With-Start will trigger an initialization step.
21+
* If the initialization step succeeds (default), intialization will return to the client with a transaction ID and the workflow will continue. The workflow will then complete and return the final result.
22+
* If the intitialization step fails (amount <= 0), the workflow will return to the client with an error message and the workflow will run an activity to cancel the transaction.
23+
24+
To trigger a failed initialization, set the amount to <= 0 in the `EarlyReturnClient` class's `runWorkflowWithUpdateWithStart` method and re-run the client.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.temporal.samples.updatewithstart;
2+
3+
public class StartWorkflowRequest {
4+
public String getValue() {
5+
return value;
6+
}
7+
8+
public void setValue(String value) {
9+
this.value = value;
10+
}
11+
12+
private String value;
13+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.updatewithstart;
21+
22+
import io.temporal.api.enums.v1.WorkflowIdConflictPolicy;
23+
import io.temporal.api.enums.v1.WorkflowIdReusePolicy;
24+
import io.temporal.client.*;
25+
import io.temporal.serviceclient.WorkflowServiceStubs;
26+
27+
public class UpdateWithStartClient {
28+
private static final String TASK_QUEUE = "UpdateWithStartTQ";
29+
private static final String WORKFLOW_ID_PREFIX = "update-with-start-";
30+
31+
public static void main(String[] args) {
32+
WorkflowClient client = setupWorkflowClient();
33+
var opts = buildWorkflowOptions();
34+
runWorkflowWithUpdateWithStart(client, opts);
35+
runWorkflowWithUpdateWithStart(client, opts);
36+
}
37+
38+
// Set up the WorkflowClient
39+
public static WorkflowClient setupWorkflowClient() {
40+
WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs();
41+
return WorkflowClient.newInstance(service);
42+
}
43+
44+
// Run workflow using 'updateWithStart'
45+
private static void runWorkflowWithUpdateWithStart(
46+
WorkflowClient client, WorkflowOptions options) {
47+
48+
var args = new StartWorkflowRequest();
49+
50+
UpdateWithStartWorkflow workflow =
51+
client.newWorkflowStub(UpdateWithStartWorkflow.class, options);
52+
53+
try {
54+
// var result =
55+
// WorkflowClient.executeUpdateWithStart(
56+
// workflow::putApplication,
57+
// args,
58+
// UpdateOptions.<UpdateWithStartWorkflowState>newBuilder().build(),
59+
// new WithStartWorkflowOperation<>(workflow::execute, args));
60+
61+
var handle =
62+
WorkflowClient.startUpdateWithStart(
63+
workflow::putApplication,
64+
args,
65+
UpdateOptions.<UpdateWithStartWorkflowState>newBuilder()
66+
.setWaitForStage(WorkflowUpdateStage.ACCEPTED)
67+
.build(),
68+
new WithStartWorkflowOperation<>(workflow::execute, args));
69+
var result = handle.getResult();
70+
71+
System.out.println(
72+
"Workflow UwS with value: "
73+
+ result.getArgs().getValue()
74+
+ ", with updates count:"
75+
+ result.getUpdates().size());
76+
77+
} catch (WorkflowExecutionAlreadyStarted e) {
78+
System.err.println("WorkflowAlreadyStarted" + e);
79+
} catch (WorkflowServiceException e) {
80+
System.err.println("WorkflowServiceException" + e.getCause());
81+
} catch (Exception e) {
82+
System.err.println(
83+
"UpdateWithStart failed: " + e.getMessage() + "/" + e.getClass().getCanonicalName());
84+
}
85+
}
86+
87+
// https://docs.temporal.io/develop/java/message-passing
88+
// Build WorkflowOptions with task queue and unique ID
89+
private static WorkflowOptions buildWorkflowOptions() {
90+
return WorkflowOptions.newBuilder()
91+
.setTaskQueue(TASK_QUEUE)
92+
.setWorkflowIdReusePolicy(
93+
WorkflowIdReusePolicy.WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE_FAILED_ONLY)
94+
.setWorkflowIdConflictPolicy(
95+
WorkflowIdConflictPolicy.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING)
96+
.setWorkflowId(WORKFLOW_ID_PREFIX + System.currentTimeMillis())
97+
.build();
98+
}
99+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.updatewithstart;
21+
22+
import io.temporal.client.WorkflowClient;
23+
import io.temporal.worker.Worker;
24+
import io.temporal.worker.WorkerFactory;
25+
26+
public class UpdateWithStartWorker {
27+
private static final String TASK_QUEUE = "UpdateWithStartTQ";
28+
29+
public static void main(String[] args) {
30+
WorkflowClient client = UpdateWithStartClient.setupWorkflowClient();
31+
startWorker(client);
32+
}
33+
34+
private static void startWorker(WorkflowClient client) {
35+
WorkerFactory factory = WorkerFactory.newInstance(client);
36+
Worker worker = factory.newWorker(TASK_QUEUE);
37+
38+
worker.registerWorkflowImplementationTypes(UpdateWithStartWorkflowImpl.class);
39+
40+
factory.start();
41+
System.out.println("Worker started");
42+
}
43+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.updatewithstart;
21+
22+
import io.temporal.workflow.UpdateMethod;
23+
import io.temporal.workflow.WorkflowInterface;
24+
import io.temporal.workflow.WorkflowMethod;
25+
26+
@WorkflowInterface
27+
public interface UpdateWithStartWorkflow {
28+
@WorkflowMethod
29+
void execute(StartWorkflowRequest args);
30+
31+
@UpdateMethod
32+
UpdateWithStartWorkflowState putApplication(StartWorkflowRequest args);
33+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.updatewithstart;
21+
22+
import io.temporal.workflow.WorkflowInit;
23+
24+
public class UpdateWithStartWorkflowImpl implements UpdateWithStartWorkflow {
25+
// private static final Logger log = LoggerFactory.getLogger(UpdateWithStartWorkflowImpl.class);
26+
private UpdateWithStartWorkflowState state;
27+
28+
@WorkflowInit
29+
public UpdateWithStartWorkflowImpl(StartWorkflowRequest args) {
30+
this.state = new UpdateWithStartWorkflowState(args);
31+
}
32+
33+
@Override
34+
public void execute(StartWorkflowRequest args) {
35+
System.out.println("execute called");
36+
// log.info("Workflow started {}", args);
37+
}
38+
39+
@Override
40+
public UpdateWithStartWorkflowState putApplication(StartWorkflowRequest args) {
41+
System.out.println("putApplication called");
42+
this.state.getUpdates().add(args);
43+
44+
return this.state;
45+
}
46+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.temporal.samples.updatewithstart;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
public class UpdateWithStartWorkflowState {
7+
private StartWorkflowRequest args;
8+
private List<StartWorkflowRequest> updates = new ArrayList<>();
9+
10+
public UpdateWithStartWorkflowState() {}
11+
12+
public UpdateWithStartWorkflowState(StartWorkflowRequest args) {
13+
this.args = args;
14+
}
15+
16+
public StartWorkflowRequest getArgs() {
17+
return args;
18+
}
19+
20+
public void setArgs(StartWorkflowRequest args) {
21+
this.args = args;
22+
}
23+
24+
public List<StartWorkflowRequest> getUpdates() {
25+
return updates;
26+
}
27+
28+
public void setUpdates(List<StartWorkflowRequest> updates) {
29+
this.updates = updates;
30+
}
31+
}

0 commit comments

Comments
 (0)