use of io.georocket.storage.RxStoreCursor in project georocket by georocket.
the class StoreEndpoint method doMerge.
/**
* Perform a search and merge all retrieved chunks using the given merger
* @param merger the merger
* @param data Data to merge into the response
* @param out the response to write the merged chunks to
* @return a single that will emit one item when all chunks have been merged
*/
private Single<Void> doMerge(Merger<ChunkMeta> merger, Single<StoreCursor> data, WriteStream<Buffer> out) {
return data.map(RxStoreCursor::new).flatMapObservable(RxStoreCursor::toObservable).flatMap(p -> store.rxGetOne(p.getRight()).flatMapObservable(crs -> merger.merge(crs, p.getLeft(), out).map(// left: count, right: not_accepted
v -> Pair.of(1L, 0L)).onErrorResumeNext(t -> {
if (t instanceof IllegalStateException) {
// ignore it, but emit a warning later
return Observable.just(Pair.of(0L, 1L));
}
return Observable.error(t);
}).doOnTerminate(() -> {
// don't forget to close the chunk!
crs.close();
})), 1).defaultIfEmpty(Pair.of(0L, 0L)).reduce((p1, p2) -> Pair.of(p1.getLeft() + p2.getLeft(), p1.getRight() + p2.getRight())).flatMap(p -> {
long count = p.getLeft();
long notaccepted = p.getRight();
if (notaccepted > 0) {
log.warn("Could not merge " + notaccepted + " chunks " + "because the merger did not accept them. Most likely " + "these are new chunks that were added while the " + "merge was in progress. If this worries you, just " + "repeat the request.");
}
if (count > 0) {
merger.finish(out);
return Observable.just(null);
} else {
return Observable.error(new FileNotFoundException("Not Found"));
}
}).toSingle().map(v -> null);
}
Aggregations