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

OPIK-75: Add client side and server side compression #227

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: 2 additions & 0 deletions apps/opik-backend/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,5 @@ authentication:

server:
enableVirtualThreads: ${ENABLE_VIRTUAL_THREADS:-false}
gzip:
enabled: true
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
import lombok.extern.slf4j.Slf4j;
import reactor.core.scheduler.Schedulers;

import java.lang.reflect.Method;

@Slf4j
public class InstrumentAsyncUtils {

Expand All @@ -30,8 +28,7 @@ public static void endSegment(Segment segment) {
Schedulers.boundedElastic().schedule(() -> {
try {
// End the segment
Method endMethod = segment.getClass().getMethod("end");
endMethod.invoke(segment);
segment.end();
} catch (Exception e) {
log.warn("Failed to end segment", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import lombok.NonNull;
import lombok.experimental.UtilityClass;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.math.BigDecimal;

Expand Down Expand Up @@ -51,4 +53,12 @@ public String writeValueAsString(@NonNull Object value) {
throw new UncheckedIOException(exception);
}
}

public void writeValueAsString(@NonNull ByteArrayOutputStream baos, @NonNull Object value) {
try {
MAPPER.writeValue(baos, value);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ private ClientSupportUtils() {
}

public static void config(ClientSupport client) {
client.getClient().register(new ConditionalGZipFilter());

client.getClient().getConfiguration().property(ClientProperties.READ_TIMEOUT, 35_000);
client.getClient().getConfiguration().connectorProvider(new GrizzlyConnectorProvider()); // Required for PATCH:
// https://github.com/dropwizard/dropwizard/discussions/6431/ Required for PATCH:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.comet.opik.api.resources.utils;


import com.comet.opik.utils.JsonUtils;
import jakarta.ws.rs.client.ClientRequestContext;
import jakarta.ws.rs.client.ClientRequestFilter;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;

public class ConditionalGZipFilter implements ClientRequestFilter {

private static final int GZIP_THRESHOLD_500KB = 500 * 1024;

@Override
public void filter(ClientRequestContext requestContext) throws IOException {

if (requestContext.hasEntity() && MediaType.APPLICATION_JSON_TYPE.equals(requestContext.getMediaType())) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
JsonUtils.writeValueAsString(baos, requestContext.getEntity()); // Serialize the entity to byte array

byte[] entityBytes = baos.toByteArray();
int entitySize = entityBytes.length;

if (entitySize > GZIP_THRESHOLD_500KB) {
ByteArrayOutputStream compressedBaos = new ByteArrayOutputStream();
try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(compressedBaos)) {
gzipOutputStream.write(entityBytes);
}

byte[] compressedEntity = compressedBaos.toByteArray();
requestContext.setEntity(compressedEntity, null, MediaType.APPLICATION_JSON_TYPE);
requestContext.getHeaders().add(HttpHeaders.CONTENT_ENCODING, "gzip");
} else {
// Use the original entity if below the threshold
requestContext.setEntity(entityBytes, null, MediaType.APPLICATION_JSON_TYPE);
}
}
}
}
2 changes: 2 additions & 0 deletions apps/opik-backend/src/test/resources/config-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,5 @@ authentication:

server:
enableVirtualThreads: ${ENABLE_VIRTUAL_THREADS:-false}
gzip:
enabled: true