Skip to content

Commit aa495d4

Browse files
author
Liang Mei
committed
remove started check in ChildWorkflowStubImpl and add unit test
1 parent 8f44379 commit aa495d4

File tree

3 files changed

+70
-9
lines changed

3 files changed

+70
-9
lines changed

src/main/java/com/uber/cadence/internal/sync/ChildWorkflowStubImpl.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ class ChildWorkflowStubImpl implements ChildWorkflowStub {
3636
private final ChildWorkflowOptions options;
3737
private final WorkflowInterceptor decisionContext;
3838
private final CompletablePromise<WorkflowExecution> execution;
39-
private boolean executionStarted;
4039

4140
ChildWorkflowStubImpl(
4241
String workflowType, ChildWorkflowOptions options, WorkflowInterceptor decisionContext) {
@@ -83,19 +82,11 @@ public <R> Promise<R> executeAsync(Class<R> returnType, Object... args) {
8382
WorkflowResult<R> result =
8483
decisionContext.executeChildWorkflow(workflowType, returnType, args, options);
8584
execution.completeFrom(result.getWorkflowExecution());
86-
executionStarted = true;
8785
return result.getResult();
8886
}
8987

9088
@Override
9189
public void signal(String signalName, Object... args) {
92-
if (!executionStarted) {
93-
throw new IllegalStateException(
94-
"This stub cannot be used to signal a workflow"
95-
+ " without starting it first. "
96-
+ "To signal a workflow execution that was started elsewhere "
97-
+ "use a stub created through Workflow.newExternalWorkflowStub");
98-
}
9990
Promise<Void> signaled =
10091
decisionContext.signalExternalWorkflow(execution.get(), signalName, args);
10192
if (AsyncInternal.isAsync()) {

src/main/java/com/uber/cadence/internal/testservice/TestWorkflowMutableStateImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ public void childWorkflowStarted(ChildWorkflowExecutionStartedEventAttributes a)
545545
String childId = a.getWorkflowExecution().getWorkflowId();
546546
StateMachine<ChildWorkflowData> child = getChildWorkflow(childId);
547547
child.action(StateMachines.Action.START, ctx, a, 0);
548+
scheduleDecision(ctx);
548549
// No need to lock until completion as child workflow might skip
549550
// time as well
550551
ctx.unlockTimer();

src/test/java/com/uber/cadence/workflow/WorkflowTest.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
import static org.junit.Assert.assertEquals;
2121
import static org.junit.Assert.assertFalse;
22+
import static org.junit.Assert.assertNotEquals;
23+
import static org.junit.Assert.assertNotNull;
2224
import static org.junit.Assert.assertNull;
2325
import static org.junit.Assert.assertTrue;
2426
import static org.junit.Assert.fail;
@@ -1011,6 +1013,73 @@ public void testChildAsyncWorkflow() {
10111013
assertEquals(null, client.execute(taskList));
10121014
}
10131015

1016+
// This workflow is designed specifically for testing some internal logic in Async.procedure
1017+
// and ChildWorkflowStubImpl. See comments on testChildAsyncLambdaWorkflow for more details.
1018+
public interface WaitOnSignalWorkflow {
1019+
1020+
@WorkflowMethod()
1021+
void execute();
1022+
1023+
@SignalMethod
1024+
void signal(String value);
1025+
}
1026+
1027+
public static class TestWaitOnSignalWorkflowImpl implements WaitOnSignalWorkflow {
1028+
private final CompletablePromise<String> signal = Workflow.newPromise();
1029+
1030+
@Override
1031+
public void execute() {
1032+
signal.get();
1033+
}
1034+
1035+
@Override
1036+
public void signal(String value) {
1037+
signal.complete(value);
1038+
}
1039+
}
1040+
1041+
public static class TestChildAsyncLambdaWorkflow implements TestWorkflow1 {
1042+
1043+
@Override
1044+
public String execute(String taskList) {
1045+
ChildWorkflowOptions workflowOptions =
1046+
new ChildWorkflowOptions.Builder()
1047+
.setExecutionStartToCloseTimeout(Duration.ofSeconds(100))
1048+
.setTaskStartToCloseTimeout(Duration.ofSeconds(60))
1049+
.setTaskList(taskList)
1050+
.build();
1051+
1052+
WaitOnSignalWorkflow child =
1053+
Workflow.newChildWorkflowStub(WaitOnSignalWorkflow.class, workflowOptions);
1054+
Promise<Void> promise = Async.procedure(() -> child.execute());
1055+
Promise<WorkflowExecution> executionPromise = Workflow.getWorkflowExecution(child);
1056+
assertNotNull(executionPromise);
1057+
WorkflowExecution execution = executionPromise.get();
1058+
assertNotEquals("", execution.getWorkflowId());
1059+
assertNotEquals("", execution.getRunId());
1060+
child.signal("test");
1061+
1062+
promise.get();
1063+
return null;
1064+
}
1065+
}
1066+
1067+
// The purpose of this test is to exercise the lambda execution logic inside Async.procedure(),
1068+
// which executes on a different thread than workflow-main. This is different than executing
1069+
// classes that implements the workflow method interface, which executes on the workflow main
1070+
// thread.
1071+
@Test
1072+
public void testChildAsyncLambdaWorkflow() {
1073+
startWorkerFor(TestChildAsyncLambdaWorkflow.class, TestWaitOnSignalWorkflowImpl.class);
1074+
1075+
WorkflowOptions.Builder options = new WorkflowOptions.Builder();
1076+
options.setExecutionStartToCloseTimeout(Duration.ofSeconds(200));
1077+
options.setTaskStartToCloseTimeout(Duration.ofSeconds(60));
1078+
options.setTaskList(taskList);
1079+
TestWorkflow1 client = workflowClient.newWorkflowStub(TestWorkflow1.class, options.build());
1080+
assertEquals(null, client.execute(taskList));
1081+
}
1082+
10141083
public static class TestUntypedChildStubWorkflow implements TestWorkflow1 {
10151084

10161085
@Override

0 commit comments

Comments
 (0)