• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

uber / cadence-java-client / 2409

03 Jul 2024 08:33PM UTC coverage: 61.467% (-0.05%) from 61.518%
2409

push

buildkite

web-flow
Avoid consuming ByteBuffers (#913)

A ByteBuffer is a pointer to a byte[] with a starting position, a current position, and a limit. Any function that reads from its contents updates the current position. Both TracingPropagator and WorkflowUtils copy the entirety of its contents, and in doing so they mutate the current position. WorkflowUtils resets it afterwards but this still isn't thread-safe as another thread may be trying to read it.

By duplicating the ByteBuffer (copying only the metadata, not the actual contents) we avoid modifying it. It doesn't seem likely that there's real impact in either of these cases beyond unit tests, where these ByteBuffers stick around in the workflow history and are repeatedly serialized/deserialized. Modifying them during serialization can create test flakiness as that can trigger exceptions.

2 of 2 new or added lines in 2 files covered. (100.0%)

10 existing lines in 4 files now uncovered.

11972 of 19477 relevant lines covered (61.47%)

0.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/main/java/com/uber/cadence/internal/compatibility/proto/DecisionMapper.java
1
/*
2
 *  Modifications Copyright (c) 2017-2021 Uber Technologies Inc.
3
 *  Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4
 *
5
 *  Licensed under the Apache License, Version 2.0 (the "License"). You may not
6
 *  use this file except in compliance with the License. A copy of the License is
7
 *  located at
8
 *
9
 *  http://aws.amazon.com/apache2.0
10
 *
11
 *  or in the "license" file accompanying this file. This file is distributed on
12
 *  an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
 *  express or implied. See the License for the specific language governing
14
 *  permissions and limitations under the License.
15
 */
16
package com.uber.cadence.internal.compatibility.proto;
17

18
import static com.uber.cadence.internal.compatibility.proto.EnumMapper.continueAsNewInitiator;
19
import static com.uber.cadence.internal.compatibility.proto.EnumMapper.parentClosePolicy;
20
import static com.uber.cadence.internal.compatibility.proto.EnumMapper.workflowIdReusePolicy;
21
import static com.uber.cadence.internal.compatibility.proto.Helpers.arrayToByteString;
22
import static com.uber.cadence.internal.compatibility.proto.Helpers.longToInt;
23
import static com.uber.cadence.internal.compatibility.proto.Helpers.secondsToDuration;
24
import static com.uber.cadence.internal.compatibility.proto.TypeMapper.activityType;
25
import static com.uber.cadence.internal.compatibility.proto.TypeMapper.failure;
26
import static com.uber.cadence.internal.compatibility.proto.TypeMapper.header;
27
import static com.uber.cadence.internal.compatibility.proto.TypeMapper.memo;
28
import static com.uber.cadence.internal.compatibility.proto.TypeMapper.payload;
29
import static com.uber.cadence.internal.compatibility.proto.TypeMapper.retryPolicy;
30
import static com.uber.cadence.internal.compatibility.proto.TypeMapper.searchAttributes;
31
import static com.uber.cadence.internal.compatibility.proto.TypeMapper.taskList;
32
import static com.uber.cadence.internal.compatibility.proto.TypeMapper.workflowExecution;
33
import static com.uber.cadence.internal.compatibility.proto.TypeMapper.workflowRunPair;
34
import static com.uber.cadence.internal.compatibility.proto.TypeMapper.workflowType;
35

36
import com.uber.cadence.api.v1.CancelTimerDecisionAttributes;
37
import com.uber.cadence.api.v1.CancelWorkflowExecutionDecisionAttributes;
38
import com.uber.cadence.api.v1.CompleteWorkflowExecutionDecisionAttributes;
39
import com.uber.cadence.api.v1.ContinueAsNewWorkflowExecutionDecisionAttributes;
40
import com.uber.cadence.api.v1.Decision;
41
import com.uber.cadence.api.v1.Decision.Builder;
42
import com.uber.cadence.api.v1.FailWorkflowExecutionDecisionAttributes;
43
import com.uber.cadence.api.v1.RecordMarkerDecisionAttributes;
44
import com.uber.cadence.api.v1.RequestCancelActivityTaskDecisionAttributes;
45
import com.uber.cadence.api.v1.RequestCancelExternalWorkflowExecutionDecisionAttributes;
46
import com.uber.cadence.api.v1.ScheduleActivityTaskDecisionAttributes;
47
import com.uber.cadence.api.v1.SignalExternalWorkflowExecutionDecisionAttributes;
48
import com.uber.cadence.api.v1.StartChildWorkflowExecutionDecisionAttributes;
49
import com.uber.cadence.api.v1.StartTimerDecisionAttributes;
50
import com.uber.cadence.api.v1.UpsertWorkflowSearchAttributesDecisionAttributes;
51
import java.util.ArrayList;
52
import java.util.List;
53

54
class DecisionMapper {
×
55

56
  static List<Decision> decisionArray(List<com.uber.cadence.Decision> t) {
57
    if (t == null) {
×
58
      return null;
×
59
    }
60

61
    List<Decision> v = new ArrayList<>();
×
62
    for (int i = 0; i < t.size(); i++) {
×
63
      v.add(decision(t.get(i)));
×
64
    }
65
    return v;
×
66
  }
67

68
  static Decision decision(com.uber.cadence.Decision d) {
69
    if (d == null) {
×
70
      return null;
×
71
    }
72
    Builder decision = Decision.newBuilder();
×
73
    switch (d.getDecisionType()) {
×
74
      case ScheduleActivityTask:
75
        {
76
          com.uber.cadence.ScheduleActivityTaskDecisionAttributes attr =
×
77
              d.getScheduleActivityTaskDecisionAttributes();
×
78
          ScheduleActivityTaskDecisionAttributes.Builder builder =
79
              ScheduleActivityTaskDecisionAttributes.newBuilder()
×
80
                  .setActivityId(attr.getActivityId())
×
81
                  .setActivityType(activityType(attr.getActivityType()))
×
82
                  .setTaskList(taskList(attr.getTaskList()))
×
83
                  .setInput(payload(attr.getInput()))
×
84
                  .setScheduleToCloseTimeout(
×
85
                      secondsToDuration(attr.getScheduleToCloseTimeoutSeconds()))
×
86
                  .setScheduleToStartTimeout(
×
87
                      secondsToDuration(attr.getScheduleToStartTimeoutSeconds()))
×
88
                  .setStartToCloseTimeout(secondsToDuration(attr.getStartToCloseTimeoutSeconds()))
×
89
                  .setHeartbeatTimeout(secondsToDuration(attr.getHeartbeatTimeoutSeconds()))
×
90
                  .setHeader(header(attr.getHeader()))
×
91
                  .setRequestLocalDispatch(attr.isRequestLocalDispatch());
×
92
          if (attr.getRetryPolicy() != null) {
×
93
            builder.setRetryPolicy(retryPolicy(attr.getRetryPolicy()));
×
94
          }
95
          if (attr.getDomain() != null) {
×
96
            builder.setDomain(attr.getDomain());
×
97
          }
98
          decision.setScheduleActivityTaskDecisionAttributes(builder);
×
99
        }
100
        break;
×
101
      case RequestCancelActivityTask:
102
        {
103
          com.uber.cadence.RequestCancelActivityTaskDecisionAttributes attr =
×
104
              d.getRequestCancelActivityTaskDecisionAttributes();
×
105
          decision.setRequestCancelActivityTaskDecisionAttributes(
×
106
              RequestCancelActivityTaskDecisionAttributes.newBuilder()
×
107
                  .setActivityId(attr.getActivityId()));
×
108
        }
109
        break;
×
110
      case StartTimer:
111
        {
112
          com.uber.cadence.StartTimerDecisionAttributes attr = d.getStartTimerDecisionAttributes();
×
113
          decision.setStartTimerDecisionAttributes(
×
114
              StartTimerDecisionAttributes.newBuilder()
×
115
                  .setTimerId(attr.getTimerId())
×
116
                  .setStartToFireTimeout(
×
117
                      secondsToDuration(longToInt(attr.getStartToFireTimeoutSeconds()))));
×
118
        }
119
        break;
×
120
      case CompleteWorkflowExecution:
121
        {
122
          com.uber.cadence.CompleteWorkflowExecutionDecisionAttributes attr =
×
123
              d.getCompleteWorkflowExecutionDecisionAttributes();
×
124
          decision.setCompleteWorkflowExecutionDecisionAttributes(
×
125
              CompleteWorkflowExecutionDecisionAttributes.newBuilder()
×
126
                  .setResult(payload(attr.getResult())));
×
127
        }
128
        break;
×
129
      case FailWorkflowExecution:
130
        {
131
          com.uber.cadence.FailWorkflowExecutionDecisionAttributes attr =
×
132
              d.getFailWorkflowExecutionDecisionAttributes();
×
133
          decision.setFailWorkflowExecutionDecisionAttributes(
×
134
              FailWorkflowExecutionDecisionAttributes.newBuilder()
×
135
                  .setFailure(failure(attr.getReason(), attr.getDetails())));
×
136
        }
137
        break;
×
138
      case CancelTimer:
139
        {
140
          com.uber.cadence.CancelTimerDecisionAttributes attr =
×
141
              d.getCancelTimerDecisionAttributes();
×
142
          decision.setCancelTimerDecisionAttributes(
×
143
              CancelTimerDecisionAttributes.newBuilder().setTimerId(attr.getTimerId()));
×
144
        }
145
        break;
×
146
      case CancelWorkflowExecution:
147
        {
148
          com.uber.cadence.CancelWorkflowExecutionDecisionAttributes attr =
×
149
              d.getCancelWorkflowExecutionDecisionAttributes();
×
150
          decision.setCancelWorkflowExecutionDecisionAttributes(
×
151
              CancelWorkflowExecutionDecisionAttributes.newBuilder()
×
152
                  .setDetails(payload(attr.getDetails())));
×
153
        }
154
        break;
×
155
      case RequestCancelExternalWorkflowExecution:
156
        {
157
          com.uber.cadence.RequestCancelExternalWorkflowExecutionDecisionAttributes attr =
×
158
              d.getRequestCancelExternalWorkflowExecutionDecisionAttributes();
×
159
          RequestCancelExternalWorkflowExecutionDecisionAttributes.Builder builder =
160
              RequestCancelExternalWorkflowExecutionDecisionAttributes.newBuilder()
×
161
                  .setDomain(attr.getDomain())
×
162
                  .setWorkflowExecution(workflowRunPair(attr.getWorkflowId(), attr.getRunId()))
×
163
                  .setChildWorkflowOnly(attr.isChildWorkflowOnly());
×
164
          if (attr.getControl() != null) {
×
165
            builder.setControl(arrayToByteString(attr.getControl()));
×
166
          }
167
          decision.setRequestCancelExternalWorkflowExecutionDecisionAttributes(builder);
×
168
        }
169
        break;
×
170
      case ContinueAsNewWorkflowExecution:
171
        {
172
          com.uber.cadence.ContinueAsNewWorkflowExecutionDecisionAttributes attr =
×
173
              d.getContinueAsNewWorkflowExecutionDecisionAttributes();
×
174
          ContinueAsNewWorkflowExecutionDecisionAttributes.Builder builder =
175
              ContinueAsNewWorkflowExecutionDecisionAttributes.newBuilder()
×
176
                  .setWorkflowType(workflowType(attr.getWorkflowType()))
×
177
                  .setTaskList(taskList(attr.getTaskList()))
×
178
                  .setInput(payload(attr.getInput()))
×
179
                  .setExecutionStartToCloseTimeout(
×
180
                      secondsToDuration(attr.getExecutionStartToCloseTimeoutSeconds()))
×
181
                  .setTaskStartToCloseTimeout(
×
182
                      secondsToDuration(attr.getTaskStartToCloseTimeoutSeconds()))
×
183
                  .setBackoffStartInterval(
×
184
                      secondsToDuration(attr.getBackoffStartIntervalInSeconds()))
×
185
                  .setInitiator(continueAsNewInitiator(attr.getInitiator()))
×
186
                  .setFailure(failure(attr.getFailureReason(), attr.getFailureDetails()))
×
187
                  .setLastCompletionResult(payload(attr.getLastCompletionResult()))
×
188
                  .setHeader(header(attr.getHeader()))
×
189
                  .setMemo(memo(attr.getMemo()))
×
190
                  .setSearchAttributes(searchAttributes(attr.getSearchAttributes()));
×
191
          if (attr.getRetryPolicy() != null) {
×
192
            builder.setRetryPolicy(retryPolicy(attr.getRetryPolicy()));
×
193
          }
194
          if (attr.getCronSchedule() != null) {
×
195
            builder.setCronSchedule(attr.getCronSchedule());
×
196
          }
197
          decision.setContinueAsNewWorkflowExecutionDecisionAttributes(builder);
×
198
        }
199
        break;
×
200
      case StartChildWorkflowExecution:
201
        {
202
          com.uber.cadence.StartChildWorkflowExecutionDecisionAttributes attr =
×
203
              d.getStartChildWorkflowExecutionDecisionAttributes();
×
204
          StartChildWorkflowExecutionDecisionAttributes.Builder builder =
205
              StartChildWorkflowExecutionDecisionAttributes.newBuilder()
×
206
                  .setDomain(attr.getDomain())
×
207
                  .setWorkflowId(attr.getWorkflowId())
×
208
                  .setWorkflowType(workflowType(attr.getWorkflowType()))
×
209
                  .setTaskList(taskList(attr.getTaskList()))
×
210
                  .setInput(payload(attr.getInput()))
×
211
                  .setExecutionStartToCloseTimeout(
×
212
                      secondsToDuration(attr.getExecutionStartToCloseTimeoutSeconds()))
×
213
                  .setTaskStartToCloseTimeout(
×
214
                      secondsToDuration(attr.getTaskStartToCloseTimeoutSeconds()))
×
215
                  .setParentClosePolicy(parentClosePolicy(attr.getParentClosePolicy()))
×
216
                  .setWorkflowIdReusePolicy(workflowIdReusePolicy(attr.getWorkflowIdReusePolicy()))
×
217
                  .setHeader(header(attr.getHeader()))
×
218
                  .setMemo(memo(attr.getMemo()))
×
219
                  .setSearchAttributes(searchAttributes(attr.getSearchAttributes()));
×
220
          if (attr.getRetryPolicy() != null) {
×
221
            builder.setRetryPolicy(retryPolicy(attr.getRetryPolicy()));
×
222
          }
223
          if (attr.getControl() != null) {
×
224
            builder.setControl(arrayToByteString(attr.getControl()));
×
225
          }
226
          if (attr.getCronSchedule() != null) {
×
227
            builder.setCronSchedule(attr.getCronSchedule());
×
228
          }
229
          decision.setStartChildWorkflowExecutionDecisionAttributes(builder);
×
230
        }
231
        break;
×
232
      case SignalExternalWorkflowExecution:
233
        {
234
          com.uber.cadence.SignalExternalWorkflowExecutionDecisionAttributes attr =
×
235
              d.getSignalExternalWorkflowExecutionDecisionAttributes();
×
236
          SignalExternalWorkflowExecutionDecisionAttributes.Builder builder =
237
              SignalExternalWorkflowExecutionDecisionAttributes.newBuilder()
×
238
                  .setDomain(attr.getDomain())
×
239
                  .setWorkflowExecution(workflowExecution(attr.getExecution()))
×
240
                  .setSignalName(attr.getSignalName())
×
241
                  .setInput(payload(attr.getInput()))
×
242
                  .setChildWorkflowOnly(attr.isChildWorkflowOnly());
×
243
          if (attr.getControl() != null) {
×
244
            builder.setControl(arrayToByteString(attr.getControl()));
×
245
          }
246
          decision.setSignalExternalWorkflowExecutionDecisionAttributes(builder);
×
247
        }
248
        break;
×
249
      case UpsertWorkflowSearchAttributes:
250
        {
251
          com.uber.cadence.UpsertWorkflowSearchAttributesDecisionAttributes attr =
×
252
              d.getUpsertWorkflowSearchAttributesDecisionAttributes();
×
253
          decision.setUpsertWorkflowSearchAttributesDecisionAttributes(
×
254
              UpsertWorkflowSearchAttributesDecisionAttributes.newBuilder()
×
255
                  .setSearchAttributes(searchAttributes(attr.getSearchAttributes())));
×
256
        }
257
        break;
×
258
      case RecordMarker:
259
        {
260
          com.uber.cadence.RecordMarkerDecisionAttributes attr =
×
261
              d.getRecordMarkerDecisionAttributes();
×
262
          decision.setRecordMarkerDecisionAttributes(
×
263
              RecordMarkerDecisionAttributes.newBuilder()
×
264
                  .setMarkerName(attr.getMarkerName())
×
265
                  .setDetails(payload(attr.getDetails()))
×
266
                  .setHeader(header(attr.getHeader())));
×
267
        }
268
        break;
×
269
      default:
270
        throw new IllegalArgumentException("unknown decision type");
×
271
    }
272
    return decision.build();
×
273
  }
274
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc