You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zipkin.apache.org by ad...@apache.org on 2019/05/08 13:01:59 UTC
[incubator-zipkin-reporter-java] 01/01: Fixes socket reset problem
in libthrift sender
This is an automated email from the ASF dual-hosted git repository.
adriancole pushed a commit to branch fix-libthrift
in repository https://gitbox.apache.org/repos/asf/incubator-zipkin-reporter-java.git
commit edbfbceab098e0abc4f14fcb2141bba6973f43a2
Author: Adrian Cole <ac...@pivotal.io>
AuthorDate: Wed May 8 21:00:47 2019 +0800
Fixes socket reset problem in libthrift sender
Before, we didn't fully read the scribe response, resulting in socket
resets.
---
.../test/java/zipkin2/reporter/TestObjects.java | 26 ++++++++++++++++++++++
.../reporter/libthrift/InternalScribeCodec.java | 4 +++-
.../reporter/libthrift/LibthriftSenderTest.java | 13 +++++++++++
3 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/core/src/test/java/zipkin2/reporter/TestObjects.java b/core/src/test/java/zipkin2/reporter/TestObjects.java
index 4a5d921..0cfe894 100644
--- a/core/src/test/java/zipkin2/reporter/TestObjects.java
+++ b/core/src/test/java/zipkin2/reporter/TestObjects.java
@@ -18,11 +18,13 @@ package zipkin2.reporter;
import java.nio.charset.Charset;
import java.util.Calendar;
+import java.util.Random;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import zipkin2.Endpoint;
import zipkin2.Span;
+// TODO: replace with zipkin-tests jar!
public final class TestObjects {
public static final Charset UTF_8 = Charset.forName("UTF-8");
/** Notably, the cassandra implementation has day granularity */
@@ -67,4 +69,28 @@ public final class TestObjects {
.putTag("http.path", "/api")
.putTag("clnt/finagle.version", "6.45.0")
.build();
+
+ static final Span.Builder spanBuilder = spanBuilder();
+
+ /** Reuse a builder as it is significantly slows tests to create 100000 of these! */
+ static Span.Builder spanBuilder() {
+ return Span.newBuilder()
+ .name("get /foo")
+ .timestamp(System.currentTimeMillis() * 1000)
+ .duration(1000)
+ .kind(Span.Kind.SERVER)
+ .localEndpoint(BACKEND)
+ .putTag("http.method", "GET");
+ }
+
+ /**
+ * Zipkin trace ids are random 64bit numbers. This creates a relatively large input to avoid
+ * flaking out due to PRNG nuance.
+ */
+ public static final Span[] LOTS_OF_SPANS =
+ new Random().longs(100_000).mapToObj(TestObjects::span).toArray(Span[]::new);
+
+ public static Span span(long traceId) {
+ return spanBuilder.traceId(Long.toHexString(traceId)).id(traceId).build();
+ }
}
diff --git a/libthrift/src/main/java/zipkin2/reporter/libthrift/InternalScribeCodec.java b/libthrift/src/main/java/zipkin2/reporter/libthrift/InternalScribeCodec.java
index eb6199d..6e643e4 100644
--- a/libthrift/src/main/java/zipkin2/reporter/libthrift/InternalScribeCodec.java
+++ b/libthrift/src/main/java/zipkin2/reporter/libthrift/InternalScribeCodec.java
@@ -78,15 +78,17 @@ public final class InternalScribeCodec { // public for zipkin-finagle
}
static boolean parseResponse(TBinaryProtocol iprot) throws TException {
+ Boolean result = null;
iprot.readStructBegin();
TField schemeField;
while ((schemeField = iprot.readFieldBegin()).type != TType.STOP) {
if (schemeField.id == 0 /* SUCCESS */ && schemeField.type == TType.I32) {
- return iprot.readI32() == 0;
+ result = iprot.readI32() == 0;
} else {
TProtocolUtil.skip(iprot, schemeField.type);
}
}
+ if (result != null) return result;
throw new TApplicationException(MISSING_RESULT, "Log failed: unknown result");
}
diff --git a/libthrift/src/test/java/zipkin2/reporter/libthrift/LibthriftSenderTest.java b/libthrift/src/test/java/zipkin2/reporter/libthrift/LibthriftSenderTest.java
index c84490b..a2f3b6f 100644
--- a/libthrift/src/test/java/zipkin2/reporter/libthrift/LibthriftSenderTest.java
+++ b/libthrift/src/test/java/zipkin2/reporter/libthrift/LibthriftSenderTest.java
@@ -17,6 +17,7 @@
package zipkin2.reporter.libthrift;
import java.io.IOException;
+import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import org.junit.After;
@@ -35,6 +36,7 @@ import static java.util.stream.Collectors.toList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
import static zipkin2.reporter.TestObjects.CLIENT_SPAN;
+import static zipkin2.reporter.TestObjects.LOTS_OF_SPANS;
public class LibthriftSenderTest {
@Rule public ExpectedException thrown = ExpectedException.none();
@@ -68,6 +70,17 @@ public class LibthriftSenderTest {
assertThat(storage.spanStore().getTraces()).containsExactly(asList(CLIENT_SPAN));
}
+ /** This will help verify sequence ID and response parsing logic works */
+ @Test
+ public void sendsSpans_multipleTimes() throws Exception {
+ for (int i = 0; i < 5; i++) { // Have client send 5 messages
+ send(Arrays.copyOfRange(LOTS_OF_SPANS, i, (i * 10) + 10));
+ }
+
+ assertThat(storage.getTraces()).flatExtracting(l -> l)
+ .contains(Arrays.copyOfRange(LOTS_OF_SPANS, 0, 50));
+ }
+
@Test
public void sendsSpansExpectedMetrics() throws Exception {
send(CLIENT_SPAN, CLIENT_SPAN);