Skip to content

Commit 1f90c28

Browse files
committed
Merge branch 'master' of github.com:motusllc/cadence-java-client
2 parents 61bb553 + 4fb1cd5 commit 1f90c28

35 files changed

+1150
-121
lines changed

.buildkite/pipeline.yml

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
steps:
2+
- label: "fossa analyze"
3+
agents:
4+
queue: "init"
5+
docker: "*"
6+
command: ".buildkite/scripts/fossa.sh"
27
- label: ":java: Unit test with test services"
38
agents:
49
queue: "workers"
@@ -28,4 +33,4 @@ steps:
2833
- docker-compose#v3.0.0:
2934
run: unit-test-docker-sticky-off
3035
config: docker/buildkite/docker-compose.yaml
31-
- wait
36+
- wait

.buildkite/scripts/fossa.sh

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
3+
set -exo pipefail
4+
5+
curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install.sh | bash -s -- -b ~/
6+
7+
~/fossa init
8+
~/fossa analyze
9+
10+
# Capture the exit status
11+
EXIT_STATUS=$?
12+
13+
echo "fossa script exits with status $EXIT_STATUS"
14+
exit $EXIT_STATUS

.fossa.yml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
version: 2
2+
cli:
3+
server: https://app.fossa.com
4+
fetcher: custom
5+
project: [email protected]:uber/cadence-java-client.git
6+
analyze:
7+
modules:
8+
- name: .
9+
type: gradle
10+
target: ':'
11+
path: .

CONTRIBUTING.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This doc is intended for contributors to `cadence-java-client` (hopefully that's
77
## Development Environment
88

99
* Java 8.
10+
* Thrift 0.9.3
1011
* Gradle build tool
1112
* Docker
1213

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ task updateDlsSubmodule(type: Exec) {
8282

8383
compileThrift {
8484
dependsOn updateDlsSubmodule
85-
sourceItems "src/main/idls/thrift/cadence.thrift","src/main/idls/thrift/shared.thrift"
85+
sourceItems "${projectDir}/src/main/idls/thrift/cadence.thrift","${projectDir}/src/main/idls/thrift/shared.thrift"
8686

8787
nowarn true
8888
}

src/main/idls

Submodule idls updated from 085f956 to 0037578

src/main/java/com/uber/cadence/activity/LocalActivityOptions.java

+18-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121

2222
import com.uber.cadence.common.MethodRetry;
2323
import com.uber.cadence.common.RetryOptions;
24+
import com.uber.cadence.context.ContextPropagator;
2425
import java.time.Duration;
26+
import java.util.List;
2527
import java.util.Objects;
2628

2729
/** Options used to configure how an local activity is invoked. */
@@ -50,12 +52,14 @@ public static LocalActivityOptions merge(
5052
ActivityOptions.mergeDuration(
5153
a.scheduleToCloseTimeoutSeconds(), o.getScheduleToCloseTimeout()))
5254
.setRetryOptions(RetryOptions.merge(r, o.getRetryOptions()))
55+
.setContextPropagators(o.getContextPropagators())
5356
.validateAndBuildWithDefaults();
5457
}
5558

5659
public static final class Builder {
5760
private Duration scheduleToCloseTimeout;
5861
private RetryOptions retryOptions;
62+
private List<ContextPropagator> contextPropagators;
5963

6064
public Builder() {}
6165

@@ -83,25 +87,32 @@ public Builder setRetryOptions(RetryOptions retryOptions) {
8387
return this;
8488
}
8589

90+
public Builder setContextPropagators(List<ContextPropagator> contextPropagators) {
91+
this.contextPropagators = contextPropagators;
92+
return this;
93+
}
94+
8695
public LocalActivityOptions build() {
87-
return new LocalActivityOptions(scheduleToCloseTimeout, retryOptions);
96+
return new LocalActivityOptions(scheduleToCloseTimeout, retryOptions, contextPropagators);
8897
}
8998

9099
public LocalActivityOptions validateAndBuildWithDefaults() {
91100
RetryOptions ro = null;
92101
if (retryOptions != null) {
93102
ro = new RetryOptions.Builder(retryOptions).validateBuildWithDefaults();
94103
}
95-
return new LocalActivityOptions(roundUpToSeconds(scheduleToCloseTimeout), ro);
104+
return new LocalActivityOptions(roundUpToSeconds(scheduleToCloseTimeout), ro, contextPropagators);
96105
}
97106
}
98107

99108
private final Duration scheduleToCloseTimeout;
100109
private final RetryOptions retryOptions;
110+
private final List<ContextPropagator> contextPropagators;
101111

102-
private LocalActivityOptions(Duration scheduleToCloseTimeout, RetryOptions retryOptions) {
112+
private LocalActivityOptions(Duration scheduleToCloseTimeout, RetryOptions retryOptions, List<ContextPropagator> contextPropagators) {
103113
this.scheduleToCloseTimeout = scheduleToCloseTimeout;
104114
this.retryOptions = retryOptions;
115+
this.contextPropagators = contextPropagators;
105116
}
106117

107118
public Duration getScheduleToCloseTimeout() {
@@ -112,6 +123,10 @@ public RetryOptions getRetryOptions() {
112123
return retryOptions;
113124
}
114125

126+
public List<ContextPropagator> getContextPropagators() {
127+
return contextPropagators;
128+
}
129+
115130
@Override
116131
public String toString() {
117132
return "LocalActivityOptions{"

src/main/java/com/uber/cadence/client/WorkflowOptions.java

+5
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ public Builder setWorkflowId(String workflowId) {
137137
* <ul>
138138
* RejectDuplicate doesn't allow new run independently of the previous run closure status.
139139
* </ul>
140+
*
141+
* <ul>
142+
* TerminateIfRunning terminate current running workflow using the same workflow ID if exist,
143+
* then start a new run in one transaction
144+
* </ul>
140145
*/
141146
public Builder setWorkflowIdReusePolicy(WorkflowIdReusePolicy workflowIdReusePolicy) {
142147
this.workflowIdReusePolicy = workflowIdReusePolicy;

src/main/java/com/uber/cadence/client/WorkflowStub.java

+17-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import com.uber.cadence.QueryRejectCondition;
2121
import com.uber.cadence.WorkflowExecution;
2222
import com.uber.cadence.internal.common.QueryResponse;
23+
import java.lang.reflect.InvocationHandler;
24+
import java.lang.reflect.Proxy;
2325
import java.lang.reflect.Type;
2426
import java.util.Optional;
2527
import java.util.concurrent.CompletableFuture;
@@ -44,19 +46,32 @@ public interface WorkflowStub {
4446
* @return untyped workflow stub for the same workflow instance.
4547
*/
4648
static <T> WorkflowStub fromTyped(T typed) {
47-
if (!(typed instanceof Supplier)) {
49+
if (!(typed instanceof Proxy)) {
4850
throw new IllegalArgumentException(
4951
"arguments must be created through WorkflowClient.newWorkflowStub");
5052
}
53+
54+
InvocationHandler handler = Proxy.getInvocationHandler(typed);
55+
56+
if (!(handler instanceof Supplier)) {
57+
throw new IllegalArgumentException(
58+
"arguments must be created through WorkflowClient.newWorkflowStub");
59+
}
60+
5161
@SuppressWarnings("unchecked")
52-
Supplier<WorkflowStub> supplier = (Supplier<WorkflowStub>) typed;
62+
Supplier<WorkflowStub> supplier = (Supplier<WorkflowStub>) handler;
5363
return supplier.get();
5464
}
5565

5666
void signal(String signalName, Object... args);
5767

5868
WorkflowExecution start(Object... args);
5969

70+
CompletableFuture<WorkflowExecution> startAsync(Object... args);
71+
72+
CompletableFuture<WorkflowExecution> startAsyncWithTimeout(
73+
long timeout, TimeUnit unit, Object... args);
74+
6075
WorkflowExecution signalWithStart(String signalName, Object[] signalArgs, Object[] startArgs);
6176

6277
Optional<String> getWorkflowType();

src/main/java/com/uber/cadence/internal/Version.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public class Version {
4343
* support. This can be used for client capibility check, on Cadence server, for backward
4444
* compatibility Format: MAJOR.MINOR.PATCH
4545
*/
46-
public static final String FEATURE_VERSION = "1.2.0";
46+
public static final String FEATURE_VERSION = "1.3.0";
4747

4848
static {
4949
// Load version from version.properties generated by Gradle into build/resources/main directory.

src/main/java/com/uber/cadence/internal/common/WorkflowExecutionUtils.java

+31-10
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public static byte[] getWorkflowExecutionResult(
125125
TimeUnit unit)
126126
throws TimeoutException, CancellationException, WorkflowExecutionFailedException,
127127
WorkflowTerminatedException, WorkflowTimedOutException, EntityNotExistsError {
128-
// getIntanceCloseEvent waits for workflow completion including new runs.
128+
// getInstanceCloseEvent waits for workflow completion including new runs.
129129
HistoryEvent closeEvent =
130130
getInstanceCloseEvent(service, domain, workflowExecution, timeout, unit);
131131
return getResultFromCloseEvent(workflowExecution, workflowType, closeEvent);
@@ -213,9 +213,12 @@ private static HistoryEvent getInstanceCloseEvent(
213213
r.setNextPageToken(pageToken);
214214
r.setWaitForNewEvent(true);
215215
r.setSkipArchival(true);
216+
RetryOptions retryOptions = getRetryOptionWithTimeout(timeout, unit);
216217
try {
217218
response =
218-
Retryer.retryWithResult(retryParameters, () -> service.GetWorkflowExecutionHistory(r));
219+
Retryer.retryWithResult(
220+
retryOptions,
221+
() -> service.GetWorkflowExecutionHistoryWithTimeout(r, unit.toMillis(timeout)));
219222
} catch (EntityNotExistsError e) {
220223
if (e.activeCluster != null
221224
&& e.currentCluster != null
@@ -289,12 +292,14 @@ private static CompletableFuture<HistoryEvent> getInstanceCloseEventAsync(
289292
request.setDomain(domain);
290293
request.setExecution(workflowExecution);
291294
request.setHistoryEventFilterType(HistoryEventFilterType.CLOSE_EVENT);
295+
request.setWaitForNewEvent(true);
292296
request.setNextPageToken(pageToken);
293297
CompletableFuture<GetWorkflowExecutionHistoryResponse> response =
294-
getWorkflowExecutionHistoryAsync(service, request);
298+
getWorkflowExecutionHistoryAsync(service, request, timeout, unit);
295299
return response.thenComposeAsync(
296300
(r) -> {
297-
if (timeout != 0 && System.currentTimeMillis() - start > unit.toMillis(timeout)) {
301+
long elapsedTime = System.currentTimeMillis() - start;
302+
if (timeout != 0 && elapsedTime > unit.toMillis(timeout)) {
298303
throw CheckedExceptionWrapper.wrap(
299304
new TimeoutException(
300305
"WorkflowId="
@@ -310,7 +315,7 @@ private static CompletableFuture<HistoryEvent> getInstanceCloseEventAsync(
310315
if (history == null || history.getEvents().size() == 0) {
311316
// Empty poll returned
312317
return getInstanceCloseEventAsync(
313-
service, domain, workflowExecution, pageToken, timeout, unit);
318+
service, domain, workflowExecution, pageToken, timeout - elapsedTime, unit);
314319
}
315320
HistoryEvent event = history.getEvents().get(0);
316321
if (!isWorkflowExecutionCompletedEvent(event)) {
@@ -326,21 +331,36 @@ private static CompletableFuture<HistoryEvent> getInstanceCloseEventAsync(
326331
.getWorkflowExecutionContinuedAsNewEventAttributes()
327332
.getNewExecutionRunId());
328333
return getInstanceCloseEventAsync(
329-
service, domain, nextWorkflowExecution, r.getNextPageToken(), timeout, unit);
334+
service,
335+
domain,
336+
nextWorkflowExecution,
337+
r.getNextPageToken(),
338+
timeout - elapsedTime,
339+
unit);
330340
}
331341
return CompletableFuture.completedFuture(event);
332342
});
333343
}
334344

345+
private static RetryOptions getRetryOptionWithTimeout(long timeout, TimeUnit unit) {
346+
return new RetryOptions.Builder(retryParameters)
347+
.setExpiration(Duration.ofSeconds(unit.toSeconds(timeout)))
348+
.build();
349+
}
350+
335351
private static CompletableFuture<GetWorkflowExecutionHistoryResponse>
336352
getWorkflowExecutionHistoryAsync(
337-
IWorkflowService service, GetWorkflowExecutionHistoryRequest r) {
353+
IWorkflowService service,
354+
GetWorkflowExecutionHistoryRequest r,
355+
long timeout,
356+
TimeUnit unit) {
357+
RetryOptions retryOptions = getRetryOptionWithTimeout(timeout, unit);
338358
return Retryer.retryWithResultAsync(
339-
retryParameters,
359+
retryOptions,
340360
() -> {
341361
CompletableFuture<GetWorkflowExecutionHistoryResponse> result = new CompletableFuture<>();
342362
try {
343-
service.GetWorkflowExecutionHistory(
363+
service.GetWorkflowExecutionHistoryWithTimeout(
344364
r,
345365
new AsyncMethodCallback<GetWorkflowExecutionHistoryResponse>() {
346366
@Override
@@ -352,7 +372,8 @@ public void onComplete(GetWorkflowExecutionHistoryResponse response) {
352372
public void onError(Exception exception) {
353373
result.completeExceptionally(exception);
354374
}
355-
});
375+
},
376+
unit.toMillis(timeout));
356377
} catch (TException e) {
357378
result.completeExceptionally(e);
358379
}

src/main/java/com/uber/cadence/internal/external/GenericWorkflowClientExternal.java

+7
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,19 @@
2626
import com.uber.cadence.internal.replay.QueryWorkflowParameters;
2727
import com.uber.cadence.internal.replay.SignalExternalWorkflowParameters;
2828
import com.uber.cadence.serviceclient.IWorkflowService;
29+
import java.util.concurrent.CompletableFuture;
2930

3031
public interface GenericWorkflowClientExternal {
3132

3233
WorkflowExecution startWorkflow(StartWorkflowExecutionParameters startParameters)
3334
throws WorkflowExecutionAlreadyStartedError;
3435

36+
CompletableFuture<WorkflowExecution> startWorkflowAsync(
37+
StartWorkflowExecutionParameters startParameters);
38+
39+
CompletableFuture<WorkflowExecution> startWorkflowAsync(
40+
StartWorkflowExecutionParameters startParameters, Long timeoutInMillis);
41+
3542
void signalWorkflowExecution(SignalExternalWorkflowParameters signalParameters);
3643

3744
WorkflowExecution signalWithStartWorkflowExecution(

0 commit comments

Comments
 (0)