io.split.client.impressions.ImpressionsManager Maven / Gradle / Ivy
package io.split.client.impressions;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import io.split.client.SplitClientConfig;
import io.split.client.dtos.KeyImpression;
import io.split.client.dtos.TestImpressions;
import io.split.engine.impressions.TreatmentLog;
import org.apache.http.impl.client.CloseableHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
/**
* Created by patricioe on 6/17/16.
*/
public class ImpressionsManager implements TreatmentLog, Runnable, Closeable {
private static final Logger _logger = LoggerFactory.getLogger(ImpressionsManager.class);
private final SplitClientConfig _config;
private final CloseableHttpClient _client;
private final BlockingQueue _queue;
private final ScheduledExecutorService _scheduler;
private final ImpressionsSender _impressionsSender;
public static ImpressionsManager instance(CloseableHttpClient client,
SplitClientConfig config) throws URISyntaxException {
return new ImpressionsManager(client, config, null);
}
public static ImpressionsManager instanceForTest(CloseableHttpClient client,
SplitClientConfig config,
ImpressionsSender impressionsSender) throws URISyntaxException {
return new ImpressionsManager(client, config, impressionsSender);
}
private ImpressionsManager(CloseableHttpClient client, SplitClientConfig config, ImpressionsSender impressionsSender) throws URISyntaxException {
_config = config;
_client = client;
_queue = new ArrayBlockingQueue(config.impressionsQueueSize());
ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setDaemon(true)
.setNameFormat("Split-ImpressionsManager-%d")
.build();
_scheduler = Executors.newSingleThreadScheduledExecutor(threadFactory);
_scheduler.scheduleAtFixedRate(this, 10, config.impressionsRefreshRate(), TimeUnit.SECONDS);
if (impressionsSender != null) {
_impressionsSender = impressionsSender;
} else {
_impressionsSender = new HttpImpressionsSender(_client, config.eventsEndpoint());
}
}
@Override
public void log(String id, String feature, String treatment, long time) {
KeyImpression impression = keyImpression(feature, id, treatment, time);
_queue.offer(impression);
}
@Override
public void close() throws IOException {
_scheduler.shutdown();
sendImpressions();
}
private KeyImpression keyImpression(String feature, String key, String treatment, long time) {
KeyImpression result = new KeyImpression();
result.feature = feature;
result.keyName = key;
result.treatment = treatment;
result.time = time;
return result;
}
@Override
public void run() {
sendImpressions();
}
private void sendImpressions() {
if (_queue.remainingCapacity() == 0) {
_logger.warn("Split SDK impressions queue is full. Impressions may have been dropped. Consider increasing capacity.");
}
long start = System.currentTimeMillis();
List impressions = new ArrayList<>(_queue.size());
_queue.drainTo(impressions);
if (impressions.isEmpty()) {
return; // Nothing to send
}
Map> tests = new HashMap<>();
for (KeyImpression ki : impressions) {
List impressionsForTest = tests.get(ki.feature);
if (impressionsForTest == null) {
impressionsForTest = new ArrayList<>();
tests.put(ki.feature, impressionsForTest);
}
impressionsForTest.add(ki);
}
List toShip = Lists.newArrayList();
for (Map.Entry> entry : tests.entrySet()) {
String testName = entry.getKey();
List keyImpressions = entry.getValue();
TestImpressions testImpressionsDTO = new TestImpressions();
testImpressionsDTO.testName = testName;
testImpressionsDTO.keyImpressions = keyImpressions;
toShip.add(testImpressionsDTO);
}
_impressionsSender.post(toShip);
if(_config.debugEnabled()) {
_logger.info(String.format("Posting %d Split impressions took %d millis",
impressions.size(), (System.currentTimeMillis() - start)));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy