Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduces the core jar from 272 to 188k by tuning codec and shade #1236

Merged
merged 2 commits into from
Aug 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Check out the [`zipkin-server`](/zipkin-server) documentation for configuration
## Core Library
The [core library](https://github.com/openzipkin/zipkin/tree/master/zipkin/src/main/java/io/zipkin) requires minimum language level 7. While currently only used by the server, we expect this library to be used in native instrumentation as well.

This includes built-in codec for both thrift and json structs. Direct dependencies on thrift or moshi (json library) are avoided by minifying and repackaging classes used. The result is a 256k jar which won't conflict with any library you use.
This includes built-in codec for both thrift and json structs. Direct dependencies on thrift or moshi (json library) are avoided by minifying and repackaging classes used. The result is a 190k jar which won't conflict with any library you use.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lie.. we actually crept up to 272K! I wrote in 190, not 188, to give a little room :)


Ex.
```java
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
package zipkin.storage.cassandra;

import com.datastax.driver.core.BoundStatement;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.ResultSetFuture;
import com.datastax.driver.core.Session;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.Reflection;
Expand All @@ -35,6 +35,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class DeduplicatingExecutorTest {
TestDeduplicatingExecutor executor = TestDeduplicatingExecutor.create(Futures::immediateFuture);
Expand Down Expand Up @@ -137,12 +138,14 @@ private void exceptionsArentCached() throws Exception {
/**
* This shows that any number of threads perform a computation only once.
*/
@Test(timeout = 2000L) // 1000 for the selects + expiration (which is 1 second)
@Test
public void multithreaded() throws Exception {
Session session = CassandraTestGraph.INSTANCE.storage.get().session();
Session session = mock(Session.class);
DeduplicatingExecutor executor =
new DeduplicatingExecutor(session, TimeUnit.SECONDS.toMillis(1L));
PreparedStatement now = session.prepare("SELECT now() FROM system.local");
BoundStatement statement = mock(BoundStatement.class);
when(session.executeAsync(statement))
.thenAnswer(invocationOnMock -> mock(ResultSetFuture.class));

int loopCount = 1000;
CountDownLatch latch = new CountDownLatch(loopCount);
Expand All @@ -151,8 +154,8 @@ public void multithreaded() throws Exception {
Collection<ListenableFuture<?>> futures = new ConcurrentLinkedDeque<>();
for (int i = 0; i < loopCount; i++) {
exec.execute(() -> {
futures.add(executor.maybeExecuteAsync(now.bind(), "foo"));
futures.add(executor.maybeExecuteAsync(now.bind(), "bar"));
futures.add(executor.maybeExecuteAsync(statement, "foo"));
futures.add(executor.maybeExecuteAsync(statement, "bar"));
latch.countDown();
});
}
Expand All @@ -166,9 +169,9 @@ public void multithreaded() throws Exception {
Thread.sleep(1000L);

// Sanity check: we don't memoize after we should have expired.
assertThat(executor.maybeExecuteAsync(now.bind(), "foo"))
assertThat(executor.maybeExecuteAsync(statement, "foo"))
.isNotIn(distinctFutures);
assertThat(executor.maybeExecuteAsync(now.bind(), "bar"))
assertThat(executor.maybeExecuteAsync(statement, "bar"))
.isNotIn(distinctFutures);
}

Expand Down
23 changes: 23 additions & 0 deletions zipkin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,29 @@
<configuration>
<shadeTestJar>false</shadeTestJar>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>com.squareup.moshi:moshi</artifact>
<includes>
<include>com/squareup/moshi/BufferedSinkJsonWriter*</include>
<include>com/squareup/moshi/BufferedSourceJsonReader*</include>
<!-- don't get zipkin/internal/moshi/JsonAdapter$Factory.class -->
<include>com/squareup/moshi/JsonAdapter.class</include>
<include>com/squareup/moshi/JsonAdapter$?.class</include>
<include>com/squareup/moshi/JsonDataException*</include>
<include>com/squareup/moshi/JsonReader*</include>
<include>com/squareup/moshi/JsonScope*</include>
<include>com/squareup/moshi/JsonWriter*</include>
</includes>
</filter>
<filter>
<!-- don't include pom files, some are kilobytes -->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/**</exclude>
</excludes>
</filter>
</filters>
<relocations>
<relocation>
<pattern>okio</pattern>
Expand Down
74 changes: 67 additions & 7 deletions zipkin/src/main/java/zipkin/internal/JsonCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import com.squareup.moshi.JsonDataException;
import com.squareup.moshi.JsonReader;
import com.squareup.moshi.JsonWriter;
import com.squareup.moshi.Moshi;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Collections;
Expand Down Expand Up @@ -122,14 +121,75 @@ public void toJson(JsonWriter writer, Endpoint value) throws IOException {
}
}.nullSafe();

static final Moshi MOSHI = new Moshi.Builder()
.add(Endpoint.class, ENDPOINT_ADAPTER)
.build();
static final JsonAdapter<Long> NULLABLE_LONG_ADAPTER = new JsonAdapter<Long>() {
@Override public Long fromJson(JsonReader reader) throws IOException {
return reader.nextLong();
}

@Override public void toJson(JsonWriter writer, Long value) throws IOException {
writer.value(value.longValue());
}

@Override public String toString() {
return "Long";
}
}.nullSafe();

static final JsonAdapter<Boolean> NULLABLE_BOOLEAN_ADAPTER = new JsonAdapter<Boolean>() {
@Override public Boolean fromJson(JsonReader reader) throws IOException {
return reader.nextBoolean();
}

@Override public void toJson(JsonWriter writer, Boolean value) throws IOException {
writer.value(value.booleanValue());
}

@Override public String toString() {
return "Boolean";
}
}.nullSafe();

public static final JsonAdapter<Annotation> ANNOTATION_ADAPTER = new JsonAdapter<Annotation>() {
@Override
public Annotation fromJson(JsonReader reader) throws IOException {
Annotation.Builder result = Annotation.builder();
reader.beginObject();
while (reader.hasNext()) {
switch (reader.nextName()) {
case "timestamp":
result.timestamp(reader.nextLong());
break;
case "value":
result.value(reader.nextString());
break;
case "endpoint":
result.endpoint(ENDPOINT_ADAPTER.fromJson(reader));
break;
default:
reader.skipValue();
}
}
reader.endObject();
return result.build();
}

static final JsonAdapter<Long> NULLABLE_LONG_ADAPTER = MOSHI.adapter(Long.class);
static final JsonAdapter<Boolean> NULLABLE_BOOLEAN_ADAPTER = MOSHI.adapter(Boolean.class);
@Override
public void toJson(JsonWriter writer, Annotation value) throws IOException {
writer.beginObject();
writer.name("timestamp").value(value.timestamp);
writer.name("value").value(value.value);
if (value.endpoint != null) {
writer.name("endpoint");
ENDPOINT_ADAPTER.toJson(writer, value.endpoint);
}
writer.endObject();
}

public static final JsonAdapter<Annotation> ANNOTATION_ADAPTER = MOSHI.adapter(Annotation.class);
@Override
public String toString() {
return "Annotation";
}
};

public static final JsonAdapter<BinaryAnnotation> BINARY_ANNOTATION_ADAPTER = new JsonAdapter<BinaryAnnotation>() {

Expand Down