/* $Id$ */
package com.linkedin.parseq.example.batching;
import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import com.linkedin.parseq.Engine;
import com.linkedin.parseq.Task;
import com.linkedin.parseq.batching.Batch;
import com.linkedin.parseq.batching.BatchingStrategy;
import com.linkedin.parseq.batching.BatchingSupport;
import com.linkedin.parseq.example.common.AbstractExample;
import com.linkedin.parseq.example.common.ExampleUtil;
/**
* @author Jaroslaw Odzga (jodzga@linkedin.com)
*/
public class BatchingClientExample extends AbstractExample {
static class KVStore {
String get(Long key) {
return String.valueOf(key);
}
Map<Long, String> batchGet(Collection<Long> keys) {
return keys.stream().collect(Collectors.toMap(key -> key, key -> get(key)));
}
}
public static class BatchingKVStoreClient extends BatchingStrategy<Integer, Long, String> {
private final KVStore _store;
public BatchingKVStoreClient(KVStore store) {
_store = store;
}
@Override
public void executeBatch(Integer group, Batch<Long, String> batch) {
Map<Long, String> batchResult = _store.batchGet(batch.keys());
batch.foreach((key, promise) -> promise.done(batchResult.get(key)));
}
@Override
public Integer classify(Long entry) {
return 0;
}
}
final KVStore store = new KVStore();
final BatchingKVStoreClient batchingStrategy = new BatchingKVStoreClient(store);
Task<String> batchableTask(final Long id) {
return batchingStrategy.batchable("fetch id: " + id, id);
}
Task<String> nonBatchableTask(final Long id) {
return Task.callable("fetch id: " + id, () -> store.get(id));
}
Task<String> branch(final Function<Long, Task<String>> client, Long base) {
return client.apply(base).flatMap("first", x -> Task.par(client.apply(base + 1), client.apply(base + 2))).flatMap("second", x -> client.apply(base + 3));
}
Task<?> plan(final Function<Long, Task<String>> client) {
return Task.par(branch(client, 1L), branch(client, 5L), branch(client, 7L));
}
@Override
protected void customizeEngine(com.linkedin.parseq.EngineBuilder engineBuilder) {
BatchingSupport batchingSupport = new BatchingSupport();
batchingSupport.registerStrategy(batchingStrategy);
engineBuilder.setPlanDeactivationListener(batchingSupport);
};
public static void main(String[] args) throws Exception {
new BatchingClientExample().runExample();
}
@Override
protected void doRunExample(final Engine engine) throws Exception {
final Task<?> nonBatchable = plan(this::nonBatchableTask);
engine.run(nonBatchable);
nonBatchable.await();
System.out.println("not batched:");
ExampleUtil.printTracingResults(nonBatchable);
System.out.println("batched:");
final Task<?> batchable = plan(this::batchableTask);
engine.run(batchable);
batchable.await();
ExampleUtil.printTracingResults(batchable);
}
}