package org.infinispan.client.hotrod.impl.operations; import java.io.InputStream; import java.util.concurrent.atomic.AtomicInteger; import org.infinispan.client.hotrod.VersionedMetadata; import org.infinispan.client.hotrod.configuration.ClientIntelligence; import org.infinispan.client.hotrod.impl.VersionedMetadataImpl; import org.infinispan.client.hotrod.impl.protocol.Codec; import org.infinispan.client.hotrod.impl.protocol.HeaderParams; import org.infinispan.client.hotrod.impl.protocol.HotRodConstants; import org.infinispan.client.hotrod.impl.transport.Transport; import org.infinispan.client.hotrod.impl.transport.TransportFactory; import net.jcip.annotations.Immutable; /** * Streaming Get operation * * @author Tristan Tarrant * @since 9.0 */ @Immutable public class GetStreamOperation<T extends InputStream & VersionedMetadata> extends AbstractKeyOperation<T> { private final int offset; private boolean retryable; public GetStreamOperation(Codec codec, TransportFactory transportFactory, Object key, byte[] keyBytes, int offset, byte[] cacheName, AtomicInteger topologyId, int flags, ClientIntelligence clientIntelligence) { super(codec, transportFactory, key, keyBytes, cacheName, topologyId, flags, clientIntelligence); this.offset = offset; retryable = true; } @Override public T executeOperation(Transport transport) { HeaderParams params = writeHeader(transport, GET_STREAM_REQUEST); transport.writeArray(keyBytes); transport.writeVInt(offset); transport.flush(); short status = readHeaderAndValidate(transport, params); T result = null; if (HotRodConstants.isNotExist(status)) { result = null; } else { if (HotRodConstants.isSuccess(status)) { retryable = false; short flags = transport.readByte(); long creation = -1; int lifespan = -1; long lastUsed = -1; int maxIdle = -1; if ((flags & INFINITE_LIFESPAN) != INFINITE_LIFESPAN) { creation = transport.readLong(); lifespan = transport.readVInt(); } if ((flags & INFINITE_MAXIDLE) != INFINITE_MAXIDLE) { lastUsed = transport.readLong(); maxIdle = transport.readVInt(); } long version = transport.readLong(); transport.setBusy(true); result = codec.readAsStream(transport, new VersionedMetadataImpl(creation, lifespan, lastUsed, maxIdle, version), () -> { transport.setBusy(false); transport.getTransportFactory().releaseTransport(transport); } ); } } return result; } @Override protected boolean shouldRetry(int retryCount) { return retryable && super.shouldRetry(retryCount); } }