
org.infinispan.client.hotrod.HotRodSyncCache Maven / Gradle / Ivy
package org.infinispan.client.hotrod;
import static org.infinispan.client.hotrod.impl.Util.await;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Flow;
import java.util.stream.Collectors;
import org.infinispan.api.Experimental;
import org.infinispan.api.async.AsyncCacheEntryProcessor;
import org.infinispan.api.common.CacheEntry;
import org.infinispan.api.common.CacheEntryVersion;
import org.infinispan.api.common.CacheOptions;
import org.infinispan.api.common.CacheWriteOptions;
import org.infinispan.api.common.CloseableIterable;
import org.infinispan.api.common.CloseableIterator;
import org.infinispan.api.common.MutableCacheEntry;
import org.infinispan.api.common.process.CacheEntryProcessorContext;
import org.infinispan.api.common.process.CacheEntryProcessorResult;
import org.infinispan.api.common.process.CacheProcessorOptions;
import org.infinispan.api.configuration.CacheConfiguration;
import org.infinispan.api.sync.SyncCache;
import org.infinispan.api.sync.SyncCacheEntryProcessor;
import org.infinispan.api.sync.SyncContainer;
import org.infinispan.api.sync.SyncQuery;
import org.infinispan.api.sync.SyncStreamingCache;
import org.infinispan.api.sync.events.cache.SyncCacheEntryListener;
import org.infinispan.client.hotrod.impl.InternalRemoteCache;
import org.reactivestreams.FlowAdapters;
import io.reactivex.rxjava3.core.Flowable;
import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.disposables.Disposable;
/**
* @since 14.0
**/
@Experimental
final class HotRodSyncCache implements SyncCache {
private final HotRod hotrod;
private final InternalRemoteCache remoteCache;
HotRodSyncCache(HotRod hotrod, InternalRemoteCache remoteCache) {
this.hotrod = hotrod;
this.remoteCache = remoteCache;
}
// This method is blocking - but only invoked by user code
@SuppressWarnings("checkstyle:ForbiddenMethod")
private E blockingGet(Single single) {
return single.blockingGet();
}
@Override
public String name() {
return remoteCache.getName();
}
@Override
public CacheConfiguration configuration() {
return null;
}
@Override
public SyncContainer container() {
return hotrod.sync();
}
@Override
public CacheEntry getEntry(K key, CacheOptions options) {
return await(remoteCache.getEntry(key, options));
}
@Override
public CacheEntry put(K key, V value, CacheWriteOptions options) {
return await(remoteCache.put(key, value, options));
}
@Override
public void set(K key, V value, CacheWriteOptions options) {
await(remoteCache.set(key, value, options));
}
@Override
public CacheEntry putIfAbsent(K key, V value, CacheWriteOptions options) {
return await(remoteCache.putIfAbsent(key, value, options));
}
@Override
public boolean setIfAbsent(K key, V value, CacheWriteOptions options) {
return await(remoteCache.setIfAbsent(key, value, options));
}
@Override
public boolean replace(K key, V value, CacheEntryVersion version, CacheWriteOptions options) {
return await(remoteCache.replace(key, value, version, options));
}
@Override
public CacheEntry getOrReplaceEntry(K key, V value, CacheEntryVersion version, CacheWriteOptions options) {
return await(remoteCache.getOrReplaceEntry(key, value, version, options));
}
@Override
public boolean remove(K key, CacheOptions options) {
return await(remoteCache.remove(key, options));
}
@Override
public boolean remove(K key, CacheEntryVersion version, CacheOptions options) {
return await(remoteCache.remove(key, version, options));
}
@Override
public CacheEntry getAndRemove(K key, CacheOptions options) {
return await(remoteCache.getAndRemove(key, options));
}
@Override
public CloseableIterable keys(CacheOptions options) {
return () -> toCloseableIterator(remoteCache.keys(options), 64);
}
@Override
public CloseableIterable> entries(CacheOptions options) {
return () -> toCloseableIterator(remoteCache.entries(options), 64);
}
private static CloseableIterator toCloseableIterator(Flow.Publisher flow, int fetchSize) {
Flowable flowable = Flowable.fromPublisher(FlowAdapters.toPublisher(flow));
@SuppressWarnings("checkstyle:forbiddenmethod")
Iterable iterable = flowable.blockingIterable(fetchSize);
Iterator iterator = iterable.iterator();
return new CloseableIterator<>() {
@Override
public void close() {
((Disposable) iterator).dispose();
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public E next() {
return iterator.next();
}
};
}
@Override
public void putAll(Map entries, CacheWriteOptions options) {
await(remoteCache.putAll(entries, options));
}
@Override
public Map getAll(Set keys, CacheOptions options) {
return blockingGet(Flowable.fromPublisher(FlowAdapters.toPublisher(remoteCache.getAll(keys, options)))
.collect(Collectors.toMap(CacheEntry::key, CacheEntry::value)));
}
@Override
public Map getAll(CacheOptions options, K[] keys) {
return blockingGet(Flowable.fromPublisher(FlowAdapters.toPublisher(remoteCache.getAll(options, keys)))
.collect(Collectors.toMap(CacheEntry::key, CacheEntry::value)));
}
@Override
public Set removeAll(Set keys, CacheWriteOptions options) {
return blockingGet(Flowable.fromPublisher(FlowAdapters.toPublisher(remoteCache.removeAll(keys, options)))
.collect(Collectors.toSet()));
}
@Override
public Map> getAndRemoveAll(Set keys, CacheWriteOptions options) {
return blockingGet(Flowable.fromPublisher(FlowAdapters.toPublisher(remoteCache.getAndRemoveAll(keys, options)))
.collect(Collectors.toMap(CacheEntry::key, ce -> ce)));
}
@Override
public long estimateSize(CacheOptions options) {
return await(remoteCache.estimateSize(options));
}
@Override
public void clear(CacheOptions options) {
await(remoteCache.clear(options));
}
@Override
public SyncQuery query(String query, CacheOptions options) {
return new HotRodSyncQuery<>();
}
@Override
public AutoCloseable listen(SyncCacheEntryListener listener) {
throw new UnsupportedOperationException();
}
@Override
public Set> process(Set keys, SyncCacheEntryProcessor processor, CacheProcessorOptions options) {
Flow.Publisher> flowPublisher = remoteCache.process(keys,
// TODO: do we worry about the sync processor here? Guessing we need to offload it to another thread ?
new SyncToAsyncEntryProcessor<>(processor), options);
return blockingGet(Flowable.fromPublisher(FlowAdapters.toPublisher(flowPublisher))
.collect(Collectors.toSet()));
}
@Override
public Set> processAll(SyncCacheEntryProcessor processor, CacheProcessorOptions options) {
Flow.Publisher> flowPublisher = remoteCache.processAll(
// TODO: do we worry about the sync processor here? Guessing we need to offload it to another thread ?
new SyncToAsyncEntryProcessor<>(processor), options);
return blockingGet(Flowable.fromPublisher(FlowAdapters.toPublisher(flowPublisher))
.collect(Collectors.toSet()));
}
@Override
public SyncStreamingCache streaming() {
return new HotRodSyncStreamingCache<>();
}
private record SyncToAsyncEntryProcessor(SyncCacheEntryProcessor processor) implements AsyncCacheEntryProcessor {
@Override
public Flow.Publisher> process(Flow.Publisher> entries, CacheEntryProcessorContext context) {
Flowable> flowable = Flowable.fromPublisher(FlowAdapters.toPublisher(entries))
.map(e -> {
try {
return CacheEntryProcessorResult.onResult(e.key(), processor.process(e, context));
} catch (Throwable t) {
return CacheEntryProcessorResult.onError(e.key(), t);
}
});
return FlowAdapters.toFlowPublisher(flowable);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy