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

uber / cadence-java-client / 2242

11 Apr 2024 07:03PM UTC coverage: 60.244% (-0.02%) from 60.263%
2242

push

buildkite

web-flow
Enable open tracing propagation in workflow lifecycles (#876)

How it works
Context Propagation in Cadence (Customer)

On start workflow API, trace span with context is written into workflow start event attributes, which is persisted in cadence server side.
On workflow-start in client, this span is referenced and activated on execute workflow.
On scheduling child workflows and activities (including local activities), the span is written into child workflow's workflow start event attributes and activity's schedule activity event attributes.
On processing activities/childworkflows, the persisted span is referenced and activated again.

Sample Spans

Notes: Poll + Respond apis spans are omitted here

{traceId:1, spanId:2, parentId:0, operationName:"cadence-RegisterDomain"}
{traceId:1, spanId:3, parentId:2, operationName:"Test Started"}
{traceId:1, spanId:18, parentId:3, operationName:"cadence-StartWorkflowExecution"}
{traceId:1, spanId:19, parentId:18, operationName:"cadence-GetWorkflowExecutionHistory"}
{traceId:1, spanId:21, parentId:18, operationName:"cadence-ExecuteWorkflow"}
{traceId:1, spanId:24, parentId:21, operationName:"cadence-ExecuteActivity"}
{traceId:1, spanId:25, parentId:24, operationName:"cadence-RespondActivityTaskCompleted"}
{traceId:1, spanId:31, parentId:21, operationName:"cadence-ExecuteWorkflow"}
{traceId:1, spanId:32, parentId:31, operationName:"cadence-ExecuteLocalActivity"}

What changed?

added an Propagator entity with tracing extract/inject logic
added trace activation logic in activity and workflow executors
added trace activation on service client (Tchannel + GRPC)
Why?

improve observability

How did you test it?

integration test

111 of 175 new or added lines in 13 files covered. (63.43%)

11 existing lines in 5 files now uncovered.

11447 of 19001 relevant lines covered (60.24%)

0.6 hits per line

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

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

18
package com.uber.cadence.internal.replay;
19

20
import com.uber.cadence.HistoryEvent;
21
import java.util.ArrayList;
22
import java.util.List;
23

24
abstract class DecisionStateMachineBase implements DecisionStateMachine {
25

26
  protected DecisionState state = DecisionState.CREATED;
1✔
27

28
  protected List<String> stateHistory = new ArrayList<String>();
1✔
29

30
  private final DecisionId id;
31

32
  public DecisionStateMachineBase(DecisionId id) {
1✔
33
    this.id = id;
1✔
34
    stateHistory.add(state.toString());
1✔
35
  }
1✔
36

37
  /** Used for unit testing. */
38
  protected DecisionStateMachineBase(DecisionId id, DecisionState state) {
×
39
    this.id = id;
×
40
    this.state = state;
×
41
    stateHistory.add(state.toString());
×
42
  }
×
43

44
  @Override
45
  public DecisionState getState() {
46
    return state;
×
47
  }
48

49
  @Override
50
  public DecisionId getId() {
51
    return id;
×
52
  }
53

54
  @Override
55
  public boolean isDone() {
56
    return state == DecisionState.COMPLETED
1✔
57
        || state == DecisionState.COMPLETED_AFTER_CANCELLATION_DECISION_SENT;
58
  }
59

60
  @Override
61
  public void handleDecisionTaskStartedEvent() {
62
    switch (state) {
1✔
63
      case CREATED:
64
        stateHistory.add("handleDecisionTaskStartedEvent");
1✔
65
        state = DecisionState.DECISION_SENT;
1✔
66
        stateHistory.add(state.toString());
1✔
67
        break;
1✔
68
      default:
69
    }
70
  }
1✔
71

72
  @Override
73
  public boolean cancel(Runnable immediateCancellationCallback) {
74
    stateHistory.add("cancel");
1✔
75
    boolean result = false;
1✔
76
    switch (state) {
1✔
77
      case CREATED:
UNCOV
78
        state = DecisionState.COMPLETED;
×
UNCOV
79
        if (immediateCancellationCallback != null) {
×
UNCOV
80
          immediateCancellationCallback.run();
×
81
        }
82
        break;
83
      case DECISION_SENT:
84
        state = DecisionState.CANCELED_BEFORE_INITIATED;
×
85
        result = true;
×
86
        break;
×
87
      case INITIATED:
88
        state = DecisionState.CANCELED_AFTER_INITIATED;
1✔
89
        result = true;
1✔
90
        break;
1✔
91
      default:
92
        failStateTransition();
×
93
    }
94
    stateHistory.add(state.toString());
1✔
95
    return result;
1✔
96
  }
97

98
  @Override
99
  public void handleInitiatedEvent(HistoryEvent event) {
100
    stateHistory.add("handleInitiatedEvent");
1✔
101
    switch (state) {
1✔
102
      case DECISION_SENT:
103
        state = DecisionState.INITIATED;
1✔
104
        break;
1✔
105
      case CANCELED_BEFORE_INITIATED:
106
        state = DecisionState.CANCELED_AFTER_INITIATED;
×
107
        break;
×
108
      default:
109
        failStateTransition();
×
110
    }
111
    stateHistory.add(state.toString());
1✔
112
  }
1✔
113

114
  @Override
115
  public void handleInitiationFailedEvent(HistoryEvent event) {
116
    stateHistory.add("handleInitiationFailedEvent");
1✔
117
    switch (state) {
1✔
118
      case INITIATED:
119
      case DECISION_SENT:
120
      case CANCELED_BEFORE_INITIATED:
121
        state = DecisionState.COMPLETED;
1✔
122
        break;
1✔
123
      default:
124
        failStateTransition();
×
125
    }
126
    stateHistory.add(state.toString());
1✔
127
  }
1✔
128

129
  @Override
130
  public void handleStartedEvent(HistoryEvent event) {
131
    stateHistory.add("handleStartedEvent");
1✔
132
  }
1✔
133

134
  @Override
135
  public void handleCompletionEvent() {
136
    stateHistory.add("handleCompletionEvent");
1✔
137
    switch (state) {
1✔
138
      case CANCELED_AFTER_INITIATED:
139
      case INITIATED:
140
        state = DecisionState.COMPLETED;
1✔
141
        break;
1✔
142
      case CANCELLATION_DECISION_SENT:
143
        state = DecisionState.COMPLETED_AFTER_CANCELLATION_DECISION_SENT;
×
144
        break;
×
145
      default:
146
        failStateTransition();
×
147
    }
148
    stateHistory.add(state.toString());
1✔
149
  }
1✔
150

151
  @Override
152
  public void handleCancellationInitiatedEvent() {
153
    stateHistory.add("handleCancellationInitiatedEvent");
1✔
154
    switch (state) {
1✔
155
      case CANCELLATION_DECISION_SENT:
156
        // No state change
157
        break;
1✔
158
      default:
159
        failStateTransition();
×
160
    }
161
    stateHistory.add(state.toString());
1✔
162
  }
1✔
163

164
  @Override
165
  public void handleCancellationFailureEvent(HistoryEvent event) {
166
    stateHistory.add("handleCancellationFailureEvent");
×
167
    switch (state) {
×
168
      case COMPLETED_AFTER_CANCELLATION_DECISION_SENT:
169
        state = DecisionState.COMPLETED;
×
170
        break;
×
171
      default:
172
        failStateTransition();
×
173
    }
174
    stateHistory.add(state.toString());
×
175
  }
×
176

177
  @Override
178
  public void handleCancellationEvent() {
179
    stateHistory.add("handleCancellationEvent");
1✔
180
    switch (state) {
1✔
181
      case CANCELLATION_DECISION_SENT:
182
        state = DecisionState.COMPLETED;
1✔
183
        break;
1✔
184
      default:
185
        failStateTransition();
×
186
    }
187
    stateHistory.add(state.toString());
1✔
188
  }
1✔
189

190
  @Override
191
  public String toString() {
192
    return "DecisionStateMachineBase [id="
×
193
        + id
194
        + ", state="
195
        + state
196
        + ", isDone="
197
        + isDone()
×
198
        + ", stateHistory="
199
        + stateHistory
200
        + "]";
201
  }
202

203
  protected void failStateTransition() {
204
    throw new IllegalStateException("id=" + id + ", transitions=" + stateHistory);
×
205
  }
206
}
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

© 2026 Coveralls, Inc