17
17
18
18
package com .uber .cadence .internal .sync ;
19
19
20
- import com .google .common .base .Defaults ;
21
- import com .uber .cadence .WorkflowExecution ;
20
+ import static com .uber .cadence .internal .common .InternalUtils .getWorkflowMethod ;
21
+ import static com .uber .cadence .internal .common .InternalUtils .getWorkflowType ;
22
+
22
23
import com .uber .cadence .activity .MethodRetry ;
23
- import com .uber .cadence .converter .DataConverter ;
24
24
import com .uber .cadence .internal .common .InternalUtils ;
25
- import com .uber .cadence .workflow .ChildWorkflowException ;
26
25
import com .uber .cadence .workflow .ChildWorkflowOptions ;
27
- import com .uber .cadence .workflow .CompletablePromise ;
28
- import com .uber .cadence .workflow .Promise ;
26
+ import com .uber .cadence .workflow .ChildWorkflowStub ;
29
27
import com .uber .cadence .workflow .QueryMethod ;
30
- import com .uber .cadence .workflow .SignalExternalWorkflowException ;
31
28
import com .uber .cadence .workflow .SignalMethod ;
32
- import com .uber .cadence .workflow .Workflow ;
33
29
import com .uber .cadence .workflow .WorkflowMethod ;
34
30
import java .lang .reflect .InvocationHandler ;
35
31
import java .lang .reflect .Method ;
36
32
37
33
/** Dynamic implementation of a strongly typed child workflow interface. */
38
34
class ChildWorkflowInvocationHandler implements InvocationHandler {
39
35
40
- private final ChildWorkflowOptions options ;
41
- private final SyncDecisionContext decisionContext ;
42
- private final DataConverter dataConverter ;
43
- private CompletablePromise <WorkflowExecution > execution = Workflow .newPromise ();
44
- private boolean startRequested ;
36
+ private final ChildWorkflowStub stub ;
45
37
46
38
ChildWorkflowInvocationHandler (
47
- ChildWorkflowOptions options , SyncDecisionContext decisionContext ) {
48
- this .options = options ;
49
- this .decisionContext = decisionContext ;
50
- dataConverter = decisionContext .getDataConverter ();
51
- }
39
+ Class <?> workflowInterface ,
40
+ ChildWorkflowOptions options ,
41
+ SyncDecisionContext decisionContext ) {
42
+ Method workflowMethod = getWorkflowMethod (workflowInterface );
43
+ WorkflowMethod workflowAnnotation = workflowMethod .getAnnotation (WorkflowMethod .class );
44
+ String workflowType = getWorkflowType (workflowMethod , workflowAnnotation );
45
+ MethodRetry retryAnnotation = workflowMethod .getAnnotation (MethodRetry .class );
52
46
53
- public ChildWorkflowInvocationHandler (
54
- WorkflowExecution execution , SyncDecisionContext decisionContext ) {
55
- this .options = null ;
56
- this .decisionContext = decisionContext ;
57
- dataConverter = decisionContext .getDataConverter ();
58
- this .execution .complete (execution );
47
+ ChildWorkflowOptions merged =
48
+ ChildWorkflowOptions .merge (workflowAnnotation , retryAnnotation , options );
49
+ this .stub = new ChildWorkflowStubImpl (workflowType , merged , decisionContext );
59
50
}
60
51
61
52
@ Override
62
53
public Object invoke (Object proxy , Method method , Object [] args ) {
63
54
// Implement WorkflowStub
64
55
if (method .getName ().equals (WorkflowStub .GET_EXECUTION_METHOD_NAME )) {
65
- return execution ;
56
+ return stub . getExecution () ;
66
57
}
67
58
WorkflowMethod workflowMethod = method .getAnnotation (WorkflowMethod .class );
68
59
QueryMethod queryMethod = method .getAnnotation (QueryMethod .class );
@@ -78,17 +69,12 @@ public Object invoke(Object proxy, Method method, Object[] args) {
78
69
+ "from @WorkflowMethod, @QueryMethod or @SignalMethod" );
79
70
}
80
71
if (workflowMethod != null ) {
81
- if (startRequested ) {
82
- throw new IllegalStateException ("Already started: " + execution );
83
- }
84
- startRequested = true ;
85
- return executeChildWorkflow (method , workflowMethod , args );
72
+ return stub .execute (method .getReturnType (), args );
86
73
}
87
74
if (queryMethod != null ) {
88
- if (execution == null ) {
89
- throw new IllegalStateException ("Workflow not started yet" );
90
- }
91
- return queryWorkflow (method , queryMethod , args );
75
+ throw new UnsupportedOperationException (
76
+ "Query is not supported from workflow to workflow. "
77
+ + "Use activity that perform the query instead." );
92
78
}
93
79
if (signalMethod != null ) {
94
80
signalWorkflow (method , signalMethod , args );
@@ -103,51 +89,6 @@ private void signalWorkflow(Method method, SignalMethod signalMethod, Object[] a
103
89
if (signalName .isEmpty ()) {
104
90
signalName = InternalUtils .getSimpleName (method );
105
91
}
106
- Promise <Void > signalled = decisionContext .signalWorkflow (execution .get (), signalName , args );
107
- if (AsyncInternal .isAsync ()) {
108
- AsyncInternal .setAsyncResult (signalled );
109
- return ;
110
- }
111
- try {
112
- signalled .get ();
113
- } catch (SignalExternalWorkflowException e ) {
114
- // Reset stack to the current one. Otherwise it is very confusing to see a stack of
115
- // an event handling method.
116
- e .setStackTrace (Thread .currentThread ().getStackTrace ());
117
- throw e ;
118
- }
119
- }
120
-
121
- private Object queryWorkflow (Method method , QueryMethod queryMethod , Object [] args ) {
122
- throw new UnsupportedOperationException (
123
- "Query is not supported from workflow to workflow. "
124
- + "Use activity that perform the query instead." );
125
- }
126
-
127
- private Object executeChildWorkflow (Method method , WorkflowMethod workflowMethod , Object [] args ) {
128
- String workflowType = workflowMethod .name ();
129
- if (workflowType .isEmpty ()) {
130
- workflowType = InternalUtils .getSimpleName (method );
131
- }
132
- byte [] input = dataConverter .toData (args );
133
- MethodRetry retry = method .getAnnotation (MethodRetry .class );
134
- ChildWorkflowOptions merged = ChildWorkflowOptions .merge (workflowMethod , retry , options );
135
- Promise <byte []> encodedResult =
136
- decisionContext .executeChildWorkflow (workflowType , merged , input , execution );
137
- Promise <?> result =
138
- encodedResult .thenApply (
139
- (encoded ) -> dataConverter .fromData (encoded , method .getReturnType ()));
140
- if (AsyncInternal .isAsync ()) {
141
- AsyncInternal .setAsyncResult (result );
142
- return Defaults .defaultValue (method .getReturnType ());
143
- }
144
- try {
145
- return result .get ();
146
- } catch (ChildWorkflowException e ) {
147
- // Reset stack to the current one. Otherwise it is very confusing to see a stack of
148
- // an event handling method.
149
- e .setStackTrace (Thread .currentThread ().getStackTrace ());
150
- throw e ;
151
- }
92
+ stub .signal (signalName , args );
152
93
}
153
94
}
0 commit comments