1
1
package datadog .trace .common .writer ;
2
2
3
+ import static java .util .concurrent .TimeUnit .MILLISECONDS ;
4
+ import static java .util .concurrent .TimeUnit .NANOSECONDS ;
5
+ import static java .util .concurrent .TimeUnit .SECONDS ;
6
+
3
7
import datadog .trace .core .DDSpan ;
4
8
import datadog .trace .core .MetadataConsumer ;
5
- import datadog .trace .core .tagprocessor .PeerServiceCalculator ;
6
- import java .util .ArrayList ;
7
9
import java .util .List ;
8
10
import java .util .concurrent .CopyOnWriteArrayList ;
9
- import java .util .concurrent .CountDownLatch ;
10
11
import java .util .concurrent .TimeUnit ;
11
12
import java .util .concurrent .TimeoutException ;
12
13
import java .util .concurrent .atomic .AtomicInteger ;
14
+ import java .util .function .BooleanSupplier ;
13
15
import org .slf4j .Logger ;
14
16
import org .slf4j .LoggerFactory ;
15
17
16
18
/** List writer used by tests mostly */
17
19
public class ListWriter extends CopyOnWriteArrayList <List <DDSpan >> implements Writer {
18
-
19
20
private static final Logger log = LoggerFactory .getLogger (ListWriter .class );
21
+ private static final Filter ACCEPT_ALL = trace -> true ;
20
22
21
- public static final Filter ACCEPT_ALL =
22
- new Filter () {
23
- @ Override
24
- public boolean accept (List <DDSpan > trace ) {
25
- return true ;
26
- }
27
- };
28
-
29
- private final List <CountDownLatch > latches = new ArrayList <>();
30
23
private final AtomicInteger traceCount = new AtomicInteger ();
31
24
private final TraceStructureWriter structureWriter = new TraceStructureWriter (true );
25
+ private final Object monitor = new Object ();
32
26
33
- private final PeerServiceCalculator peerServiceCalculator = new PeerServiceCalculator ();
34
27
private Filter filter = ACCEPT_ALL ;
35
28
36
29
public List <DDSpan > firstTrace () {
@@ -47,30 +40,44 @@ public void write(List<DDSpan> trace) {
47
40
// remotely realistic so the test actually test something
48
41
span .processTagsAndBaggage (MetadataConsumer .NO_OP );
49
42
}
43
+
44
+ add (trace );
45
+ structureWriter .write (trace );
46
+
50
47
traceCount .incrementAndGet ();
51
- synchronized (latches ) {
52
- add (trace );
53
- for (final CountDownLatch latch : latches ) {
54
- if (size () >= latch .getCount ()) {
55
- while (latch .getCount () > 0 ) {
56
- latch .countDown ();
57
- }
58
- }
59
- }
48
+ synchronized (monitor ) {
49
+ monitor .notifyAll ();
60
50
}
61
- structureWriter .write (trace );
62
51
}
63
52
64
- public boolean waitForTracesMax (final int number , int seconds )
65
- throws InterruptedException , TimeoutException {
66
- final CountDownLatch latch = new CountDownLatch (number );
67
- synchronized (latches ) {
68
- if (size () >= number ) {
53
+ private boolean awaitUntilDeadline (long timeout , TimeUnit unit , BooleanSupplier predicate )
54
+ throws InterruptedException {
55
+ final long deadline = System .nanoTime () + unit .toNanos (timeout );
56
+
57
+ while (true ) {
58
+ if (predicate .getAsBoolean ()) {
69
59
return true ;
70
60
}
71
- latches .add (latch );
61
+
62
+ long now = System .nanoTime ();
63
+ long remaining = deadline - now ;
64
+ if (remaining <= 0 ) {
65
+ break ;
66
+ }
67
+
68
+ long millis = NANOSECONDS .toMillis (remaining );
69
+ long nanos = remaining - MILLISECONDS .toNanos (millis );
70
+
71
+ synchronized (monitor ) {
72
+ monitor .wait (millis , (int ) nanos );
73
+ }
72
74
}
73
- return latch .await (seconds , TimeUnit .SECONDS );
75
+
76
+ return false ;
77
+ }
78
+
79
+ public boolean waitForTracesMax (final int number , int seconds ) throws InterruptedException {
80
+ return awaitUntilDeadline (seconds , SECONDS , () -> traceCount .get () >= number );
74
81
}
75
82
76
83
public void waitForTraces (final int number ) throws InterruptedException , TimeoutException {
@@ -88,24 +95,17 @@ public void waitForTraces(final int number) throws InterruptedException, Timeout
88
95
}
89
96
90
97
public void waitUntilReported (final DDSpan span ) throws InterruptedException , TimeoutException {
91
- waitUntilReported (span , 20 , TimeUnit . SECONDS );
98
+ waitUntilReported (span , 20 , SECONDS );
92
99
}
93
100
94
101
public void waitUntilReported (final DDSpan span , int timeout , TimeUnit unit )
95
102
throws InterruptedException , TimeoutException {
96
- while (true ) {
97
- final CountDownLatch latch = new CountDownLatch (size () + 1 );
98
- synchronized (latches ) {
99
- latches .add (latch );
100
- }
101
- if (isReported (span )) {
102
- return ;
103
- }
104
- if (!latch .await (timeout , unit )) {
105
- String msg = "Timeout waiting for span to be reported: " + span ;
106
- log .warn (msg );
107
- throw new TimeoutException (msg );
108
- }
103
+ boolean reported = awaitUntilDeadline (timeout , unit , () -> isReported (span ));
104
+
105
+ if (!reported ) {
106
+ String msg = "Timeout waiting for span to be reported: " + span ;
107
+ log .warn (msg );
108
+ throw new TimeoutException (msg );
109
109
}
110
110
}
111
111
@@ -142,17 +142,16 @@ public boolean flush() {
142
142
return true ;
143
143
}
144
144
145
+ @ Override
146
+ public void clear () {
147
+ super .clear ();
148
+
149
+ traceCount .set (0 );
150
+ }
151
+
145
152
@ Override
146
153
public void close () {
147
154
clear ();
148
- synchronized (latches ) {
149
- for (final CountDownLatch latch : latches ) {
150
- while (latch .getCount () > 0 ) {
151
- latch .countDown ();
152
- }
153
- }
154
- latches .clear ();
155
- }
156
155
}
157
156
158
157
@ Override
0 commit comments