-
Notifications
You must be signed in to change notification settings - Fork 96
/
DefaultStreamingStrategy.java
127 lines (112 loc) · 4.24 KB
/
DefaultStreamingStrategy.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.amazonaws.xray.strategy;
import com.amazonaws.xray.emitters.Emitter;
import com.amazonaws.xray.entities.Entity;
import com.amazonaws.xray.entities.Segment;
import com.amazonaws.xray.entities.Subsegment;
import java.util.ArrayList;
public class DefaultStreamingStrategy implements StreamingStrategy {
private static final int DEFAULT_MAX_SEGMENT_SIZE = 100;
private final int maxSegmentSize;
/**
* Constructs an instance of DefaultStreamingStrategy using the default {@code maxSegmentSize} of 100.
*
*/
public DefaultStreamingStrategy() {
this(DEFAULT_MAX_SEGMENT_SIZE);
}
/**
* Constructs an instance of DefaultStreamingStrategy using the provided {@code maxSegmentSize}.
*
* @param maxSegmentSize
* the maximum number of subsegment nodes a segment tree may have before {@code requiresStreaming} will return true
*
* @throws IllegalArgumentException
* when {@code maxSegmentSize} is a negative integer
*
*/
public DefaultStreamingStrategy(int maxSegmentSize) {
if (maxSegmentSize < 0) {
throw new IllegalArgumentException("maxSegmentSize must be a non-negative integer.");
}
this.maxSegmentSize = maxSegmentSize;
}
public int getMaxSegmentSize() {
return maxSegmentSize;
}
/**
* {@inheritDoc}
*
* Indicates that the provided segment requires streaming when it has been marked for sampling and its tree of subsegments
* reaches a size greater than {@code maxSegmentSize}.
*
* @see StreamingStrategy#requiresStreaming(Segment)
*/
@Override
public boolean requiresStreaming(Segment segment) {
if (segment.isSampled() && null != segment.getTotalSize()) {
return segment.getTotalSize().intValue() > maxSegmentSize;
}
return false;
}
/**
* {@inheritDoc}
*
* Performs Subtree Subsegment Streaming to stream completed subsegment subtrees. Serializes these subtrees of subsegments,
* streams them to the daemon, and removes them from their parents.
*
* @see StreamingStrategy#streamSome(Entity,Emitter)
*/
@Override
public void streamSome(Entity entity, Emitter emitter) {
if (entity.getSubsegmentsLock().tryLock()) {
try {
stream(entity, emitter);
} finally {
entity.getSubsegmentsLock().unlock();
}
}
}
private boolean stream(Entity entity, Emitter emitter) {
ArrayList<Subsegment> children = new ArrayList<>(entity.getSubsegments());
ArrayList<Subsegment> streamable = new ArrayList<>();
//Gather children and in the condition they are ready to stream, add them to the streamable list.
if (children.size() > 0) {
for (Subsegment child : children) {
if (child.getSubsegmentsLock().tryLock()) {
try {
if (stream(child, emitter)) {
streamable.add(child);
}
} finally {
child.getSubsegmentsLock().unlock();
}
}
}
}
//A subsegment is marked streamable if all of its children are streamable and the entity itself is not in progress.
if (children.size() == streamable.size() && !entity.isInProgress()) {
return true;
}
//Stream the subtrees that are ready.
for (Subsegment child : streamable) {
emitter.sendSubsegment(child);
child.setEmitted(true);
entity.removeSubsegment(child);
}
return false;
}
}