All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netflix.dyno.jedis.DynoJedisPipeline Maven / Gradle / Ivy

There is a newer version: 1.9.1
Show newest version
/**
 * Copyright 2016 Netflix, Inc.
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.netflix.dyno.jedis; import com.google.common.base.Strings; import com.netflix.dyno.connectionpool.*; import com.netflix.dyno.connectionpool.Connection; import com.netflix.dyno.connectionpool.exception.DynoException; import com.netflix.dyno.connectionpool.exception.FatalConnectionException; import com.netflix.dyno.connectionpool.exception.NoAvailableHostsException; import com.netflix.dyno.connectionpool.impl.ConnectionPoolImpl; import com.netflix.dyno.connectionpool.impl.utils.CollectionUtils; import com.netflix.dyno.connectionpool.impl.utils.ZipUtils; import com.netflix.dyno.jedis.JedisConnectionFactory.JedisConnection; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.*; import redis.clients.jedis.commands.BinaryRedisPipeline; import redis.clients.jedis.commands.RedisPipeline; import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.params.GeoRadiusParam; import redis.clients.jedis.params.SetParams; import redis.clients.jedis.params.ZAddParams; import redis.clients.jedis.params.ZIncrByParams; import javax.annotation.concurrent.NotThreadSafe; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import static com.netflix.dyno.connectionpool.ConnectionPoolConfiguration.CompressionStrategy; @NotThreadSafe public class DynoJedisPipeline implements RedisPipeline, BinaryRedisPipeline, AutoCloseable { private static final Logger Logger = LoggerFactory.getLogger(DynoJedisPipeline.class); // ConnPool and connection to exec the pipeline private final ConnectionPoolImpl connPool; private volatile Connection connection; private final DynoJedisPipelineMonitor opMonitor; private final ConnectionPoolMonitor cpMonitor; // the cached pipeline private volatile Pipeline jedisPipeline = null; // the cached row key for the pipeline. all subsequent requests to pipeline // must be the same. this is used to check that. private final AtomicReference theKey = new AtomicReference(null); private final AtomicReference theBinaryKey = new AtomicReference(null); private final AtomicReference hashtag = new AtomicReference(null); // used for tracking errors private final AtomicReference pipelineEx = new AtomicReference(null); private static final String DynoPipeline = "DynoPipeline"; DynoJedisPipeline(ConnectionPoolImpl cPool, DynoJedisPipelineMonitor operationMonitor, ConnectionPoolMonitor connPoolMonitor) { this.connPool = cPool; this.opMonitor = operationMonitor; this.cpMonitor = connPoolMonitor; } private void pipelined(final byte[] key) { try { try { connection = connPool.getConnectionForOperation(new BaseOperation() { @Override public String getName() { return DynoPipeline; } @Override public String getStringKey() {// we do not use it in this context return null; } @Override public byte[] getBinaryKey() { return key; } }); } catch (NoAvailableHostsException nahe) { cpMonitor.incOperationFailure(connection != null ? connection.getHost() : null, nahe); discardPipelineAndReleaseConnection(); throw nahe; } } catch (NoAvailableHostsException nahe) { cpMonitor.incOperationFailure(connection != null ? connection.getHost() : null, nahe); discardPipelineAndReleaseConnection(); throw nahe; } Jedis jedis = ((JedisConnection) connection).getClient(); jedisPipeline = jedis.pipelined(); cpMonitor.incOperationSuccess(connection.getHost(), 0); } private void pipelined(final String key) { try { try { connection = connPool.getConnectionForOperation(new BaseOperation() { @Override public String getName() { return DynoPipeline; } @Override public String getStringKey() { return key; } @Override public byte[] getBinaryKey() { // we do not use it in this context return null; } }); } catch (NoAvailableHostsException nahe) { cpMonitor.incOperationFailure(connection != null ? connection.getHost() : null, nahe); discardPipelineAndReleaseConnection(); throw nahe; } } catch (NoAvailableHostsException nahe) { cpMonitor.incOperationFailure(connection != null ? connection.getHost() : null, nahe); discardPipelineAndReleaseConnection(); throw nahe; } Jedis jedis = ((JedisConnection) connection).getClient(); jedisPipeline = jedis.pipelined(); cpMonitor.incOperationSuccess(connection.getHost(), 0); } private void checkHashtag(final String key, final String hashtagValue) { if (this.hashtag.get() != null) { verifyHashtagValue(hashtagValue); } else { boolean success = this.hashtag.compareAndSet(null, hashtagValue); if (!success) { verifyHashtagValue(hashtagValue); } else { pipelined(key); } } } /** * Checks that a pipeline is associated with a single key. Binary keys do not * support hashtags. * * @param key */ private void checkKey(final byte[] key) { if (theBinaryKey.get() != null) { verifyKey(key); } else { boolean success = theBinaryKey.compareAndSet(null, key); if (!success) { // someone already beat us to it. that's fine, just verify // that the key is the same verifyKey(key); } else { pipelined(key); } } } /** * Checks that a pipeline is associated with a single key. If there is a hashtag * defined in the first host of the connectionpool then we check that first. * * @param key */ private void checkKey(final String key) { /* * Get hashtag from the first host of the active pool We cannot use the * connection object because as of now we have not selected a connection. A * connection is selected based on the key or hashtag respectively. */ String hashtag = connPool.getConfiguration().getHashtag(); if (hashtag == null || hashtag.isEmpty()) { if (theKey.get() != null) { verifyKey(key); } else { boolean success = theKey.compareAndSet(null, key); if (!success) { // someone already beat us to it. that's fine, just verify // that the key is the same verifyKey(key); } else { pipelined(key); } } } else { /* * We have a identified a hashtag in the Host object. That means Dynomite has a * defined hashtag. Producing the hashvalue out of the hashtag and using that as * a reference to the pipeline */ String hashValue = StringUtils.substringBetween(key, Character.toString(hashtag.charAt(0)), Character.toString(hashtag.charAt(1))); if (Strings.isNullOrEmpty(hashValue)) { hashValue = key; } checkHashtag(key, hashValue); } } /** * Verifies binary key with pipeline binary key */ private void verifyKey(final byte[] key) { if (!theBinaryKey.get().equals(key)) { try { throw new RuntimeException("Must have same key for Redis Pipeline in Dynomite. This key: " + key); } finally { discardPipelineAndReleaseConnection(); } } } /** * Verifies key with pipeline key */ private void verifyKey(final String key) { if (!theKey.get().equals(key)) { try { throw new RuntimeException("Must have same key for Redis Pipeline in Dynomite. This key: " + key); } finally { discardPipelineAndReleaseConnection(); } } } private void verifyHashtagValue(final String hashtagValue) { if (!this.hashtag.get().equals(hashtagValue)) { try { throw new RuntimeException( "Must have same hashtag for Redis Pipeline in Dynomite. This hashvalue: " + hashtagValue); } finally { discardPipelineAndReleaseConnection(); } } } private String decompressValue(String value) { try { if (ZipUtils.isCompressed(value)) { return ZipUtils.decompressFromBase64String(value); } } catch (IOException e) { Logger.warn("Unable to decompress value [" + value + "]"); } return value; } private byte[] decompressValue(byte[] value) { try { if (ZipUtils.isCompressed(value)) { return ZipUtils.decompressBytesNonBase64(value); } } catch (IOException e) { Logger.warn("Unable to decompress byte array value [" + value + "]"); } return value; } /** * As long as jdk 7 and below is supported we need to define our own function * interfaces */ private interface Func0 { R call(); } public class PipelineResponse extends Response { private Response response; public PipelineResponse(Builder b) { super(BuilderFactory.STRING); } public PipelineResponse apply(Func0> f) { this.response = f.call(); return this; } @Override public String get() { return decompressValue(response.get()); } } public class PipelineLongResponse extends Response { private Response response; public PipelineLongResponse(Builder b) { super(b); } public PipelineLongResponse apply(Func0> f) { this.response = f.call(); return this; } } public class PipelineListResponse extends Response> { private Response> response; public PipelineListResponse(Builder b) { super(BuilderFactory.STRING_LIST); } public PipelineListResponse apply(Func0>> f) { this.response = f.call(); return this; } @Override public List get() { return new ArrayList( CollectionUtils.transform(response.get(), new CollectionUtils.Transform() { @Override public String get(String s) { return decompressValue(s); } })); } } public class PipelineBinaryResponse extends Response { private Response response; public PipelineBinaryResponse(Builder b) { super(BuilderFactory.BYTE_ARRAY); } public PipelineBinaryResponse apply(Func0> f) { this.response = f.call(); return this; } @Override public byte[] get() { return decompressValue(response.get()); } } public class PipelineMapResponse extends Response> { private Response> response; public PipelineMapResponse(Builder> b) { super(BuilderFactory.STRING_MAP); } @Override public Map get() { return CollectionUtils.transform(response.get(), new CollectionUtils.MapEntryTransform() { @Override public String get(String key, String val) { return decompressValue(val); } }); } } public class PipelineBinaryMapResponse extends Response> { private Response> response; public PipelineBinaryMapResponse(Builder> b) { super(BuilderFactory.BYTE_ARRAY_MAP); } public PipelineBinaryMapResponse apply(Func0>> f) { this.response = f.call(); return this; } @Override public Map get() { return CollectionUtils.transform(response.get(), new CollectionUtils.MapEntryTransform() { @Override public byte[] get(byte[] key, byte[] val) { return decompressValue(val); } }); } } private abstract class PipelineOperation { abstract Response execute(Pipeline jedisPipeline) throws DynoException; Response execute(final byte[] key, final OpName opName) { checkKey(key); return executeOperation(opName); } Response execute(final String key, final OpName opName) { checkKey(key); return executeOperation(opName); } Response executeOperation(final OpName opName) { try { opMonitor.recordOperation(opName.name()); return execute(jedisPipeline); } catch (JedisConnectionException ex) { handleConnectionException(ex); throw ex; } } void handleConnectionException(JedisConnectionException ex) { DynoException e = new FatalConnectionException(ex).setAttempt(1); pipelineEx.set(e); cpMonitor.incOperationFailure(connection.getHost(), e); } } private abstract class PipelineCompressionOperation extends PipelineOperation { /** * Compresses the value based on the threshold defined by * {@link ConnectionPoolConfiguration#getValueCompressionThreshold()} * * @param value * @return */ public String compressValue(String value) { String result = value; int thresholdBytes = connPool.getConfiguration().getValueCompressionThreshold(); try { // prefer speed over accuracy here so rather than using // getBytes() to get the actual size // just estimate using 2 bytes per character if ((2 * value.length()) > thresholdBytes) { result = ZipUtils.compressStringToBase64String(value); } } catch (IOException e) { Logger.warn("UNABLE to compress [" + value + "]; sending value uncompressed"); } return result; } public byte[] compressValue(byte[] value) { int thresholdBytes = connPool.getConfiguration().getValueCompressionThreshold(); if (value.length > thresholdBytes) { try { return ZipUtils.compressBytesNonBase64(value); } catch (IOException e) { Logger.warn("UNABLE to compress byte array [" + value + "]; sending value uncompressed"); } } return value; } } @Override public Response append(final String key, final String value) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.append(key, value); } }.execute(key, OpName.APPEND); } @Override public Response> blpop(final String arg) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.blpop(arg); } }.execute(arg, OpName.BLPOP); } @Override public Response> brpop(final String arg) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.brpop(arg); } }.execute(arg, OpName.BRPOP); } @Override public Response decr(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.decr(key); } }.execute(key, OpName.DECR); } @Override public Response decrBy(final String key, final long integer) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.decrBy(key, integer); } }.execute(key, OpName.DECRBY); } @Override public Response del(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.del(key); } }.execute(key, OpName.DEL); } @Override public Response unlink(String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.unlink(key); } }.execute(key, OpName.UNLINK); } @Override public Response echo(final String string) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.echo(string); } }.execute(string, OpName.ECHO); } @Override public Response exists(final String key) { return new PipelineOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { return jedisPipeline.exists(key); } }.execute(key, OpName.EXISTS); } @Override public Response expire(final String key, final int seconds) { return new PipelineOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { long startTime = System.nanoTime() / 1000; try { return jedisPipeline.expire(key, seconds); } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordSendLatency(OpName.EXPIRE.name(), duration, TimeUnit.MICROSECONDS); } } }.execute(key, OpName.EXPIRE); } @Override public Response pexpire(String key, long milliseconds) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response expireAt(final String key, final long unixTime) { return new PipelineOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { return jedisPipeline.expireAt(key, unixTime); } }.execute(key, OpName.EXPIREAT); } @Override public Response pexpireAt(String key, long millisecondsTimestamp) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response get(final String key) { if (CompressionStrategy.NONE == connPool.getConfiguration().getCompressionStrategy()) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { long startTime = System.nanoTime() / 1000; try { return jedisPipeline.get(key); } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordSendLatency(OpName.GET.name(), duration, TimeUnit.MICROSECONDS); } } }.execute(key, OpName.GET); } else { return new PipelineCompressionOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { return new PipelineResponse(null).apply(new Func0>() { @Override public Response call() { return jedisPipeline.get(key); } }); } }.execute(key, OpName.GET); } } @Override public Response getbit(final String key, final long offset) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.getbit(key, offset); } }.execute(key, OpName.GETBIT); } @Override public Response getrange(final String key, final long startOffset, final long endOffset) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.getrange(key, startOffset, endOffset); } }.execute(key, OpName.GETRANGE); } @Override public Response getSet(final String key, final String value) { if (CompressionStrategy.NONE == connPool.getConfiguration().getCompressionStrategy()) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.getSet(key, value); } }.execute(key, OpName.GETSET); } else { return new PipelineCompressionOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { return new PipelineResponse(null).apply(new Func0>() { @Override public Response call() { return jedisPipeline.getSet(key, compressValue(value)); } }); } }.execute(key, OpName.GETSET); } } @Override public Response hdel(final String key, final String... field) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.hdel(key, field); } }.execute(key, OpName.HDEL); } @Override public Response hexists(final String key, final String field) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.hexists(key, field); } }.execute(key, OpName.HEXISTS); } @Override public Response hget(final String key, final String field) { if (CompressionStrategy.NONE == connPool.getConfiguration().getCompressionStrategy()) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.hget(key, field); } }.execute(key, OpName.HGET); } else { return new PipelineCompressionOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { return new PipelineResponse(null).apply(new Func0>() { @Override public Response call() { return jedisPipeline.hget(key, field); } }); } }.execute(key, OpName.HGET); } } /** * This method is a BinaryRedisPipeline command which dyno does not yet properly * support, therefore the interface is not yet implemented. */ public Response hget(final byte[] key, final byte[] field) { if (CompressionStrategy.NONE == connPool.getConfiguration().getCompressionStrategy()) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.hget(key, field); } }.execute(key, OpName.HGET); } else { return new PipelineCompressionOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { return new PipelineBinaryResponse(null).apply(new Func0>() { @Override public Response call() { return jedisPipeline.hget(key, field); } }); } }.execute(key, OpName.HGET); } } @Override public Response> hgetAll(final String key) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { long startTime = System.nanoTime() / 1000; try { return jedisPipeline.hgetAll(key); } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordSendLatency(OpName.HGETALL.name(), duration, TimeUnit.MICROSECONDS); } } }.execute(key, OpName.HGETALL); } public Response> hgetAll(final byte[] key) { if (CompressionStrategy.NONE == connPool.getConfiguration().getCompressionStrategy()) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { long startTime = System.nanoTime() / 1000; try { return jedisPipeline.hgetAll(key); } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordSendLatency(OpName.HGETALL.name(), duration, TimeUnit.MICROSECONDS); } } }.execute(key, OpName.HGETALL); } else { return new PipelineCompressionOperation>() { @Override Response> execute(final Pipeline jedisPipeline) throws DynoException { return new PipelineBinaryMapResponse(null).apply(new Func0>>() { @Override public Response> call() { return jedisPipeline.hgetAll(key); } }); } }.execute(key, OpName.HGETALL); } } @Override public Response hincrBy(final String key, final String field, final long value) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.hincrBy(key, field, value); } }.execute(key, OpName.HINCRBY); } /* not supported by RedisPipeline 2.7.3 */ public Response hincrByFloat(final String key, final String field, final double value) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.hincrByFloat(key, field, value); } }.execute(key, OpName.HINCRBYFLOAT); } @Override public Response> hkeys(final String key) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.hkeys(key); } }.execute(key, OpName.HKEYS); } public Response>> hscan(final String key, int cursor) { throw new UnsupportedOperationException("'HSCAN' cannot be called in pipeline"); } @Override public Response hlen(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.hlen(key); } }.execute(key, OpName.HLEN); } /** * This method is a BinaryRedisPipeline command which dyno does not yet properly * support, therefore the interface is not yet implemented. */ public Response> hmget(final byte[] key, final byte[]... fields) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { long startTime = System.nanoTime() / 1000; try { return jedisPipeline.hmget(key, fields); } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordSendLatency(OpName.HMGET.name(), duration, TimeUnit.MICROSECONDS); } } }.execute(key, OpName.HMGET); } @Override public Response> hmget(final String key, final String... fields) { if (CompressionStrategy.NONE == connPool.getConfiguration().getCompressionStrategy()) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { long startTime = System.nanoTime() / 1000; try { return jedisPipeline.hmget(key, fields); } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordSendLatency(OpName.HMGET.name(), duration, TimeUnit.MICROSECONDS); } } }.execute(key, OpName.HMGET); } else { return new PipelineCompressionOperation>() { @Override Response> execute(final Pipeline jedisPipeline) throws DynoException { long startTime = System.nanoTime() / 1000; try { return new PipelineListResponse(null).apply(new Func0>>() { @Override public Response> call() { return jedisPipeline.hmget(key, fields); } }); } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordSendLatency(OpName.HMGET.name(), duration, TimeUnit.MICROSECONDS); } } }.execute(key, OpName.HGET); } } /** * This method is a BinaryRedisPipeline command which dyno does not yet properly * support, therefore the interface is not yet implemented since only a few * binary commands are present. */ public Response hmset(final byte[] key, final Map hash) { if (CompressionStrategy.NONE == connPool.getConfiguration().getCompressionStrategy()) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { long startTime = System.nanoTime() / 1000; try { return jedisPipeline.hmset(key, hash); } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordSendLatency(OpName.HMSET.name(), duration, TimeUnit.MICROSECONDS); } } }.execute(key, OpName.HMSET); } else { return new PipelineCompressionOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { return new PipelineResponse(null).apply(new Func0>() { @Override public Response call() { return jedisPipeline.hmset(key, CollectionUtils.transform(hash, new CollectionUtils.MapEntryTransform() { @Override public byte[] get(byte[] key, byte[] val) { return compressValue(val); } })); } }); } }.execute(key, OpName.HMSET); } } @Override public Response hmset(final String key, final Map hash) { if (CompressionStrategy.NONE == connPool.getConfiguration().getCompressionStrategy()) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { long startTime = System.nanoTime() / 1000; try { return jedisPipeline.hmset(key, hash); } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordSendLatency(OpName.HMSET.name(), duration, TimeUnit.MICROSECONDS); } } }.execute(key, OpName.HMSET); } else { return new PipelineCompressionOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { return new PipelineResponse(null).apply(new Func0>() { @Override public Response call() { return jedisPipeline.hmset(key, CollectionUtils.transform(hash, new CollectionUtils.MapEntryTransform() { @Override public String get(String key, String val) { return compressValue(val); } })); } }); } }.execute(key, OpName.HMSET); } } @Override public Response hset(final String key, final String field, final String value) { if (CompressionStrategy.NONE == connPool.getConfiguration().getCompressionStrategy()) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.hset(key, field, value); } }.execute(key, OpName.HSET); } else { return new PipelineCompressionOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { return new PipelineLongResponse(null).apply(new Func0>() { @Override public Response call() { return jedisPipeline.hset(key, field, compressValue(value)); } }); } }.execute(key, OpName.HSET); } } @Override public Response hset(String key, Map hash) { throw new UnsupportedOperationException("not yet implemented"); } /** * This method is a BinaryRedisPipeline command which dyno does not yet properly * support, therefore the interface is not yet implemented. */ public Response hset(final byte[] key, final byte[] field, final byte[] value) { if (CompressionStrategy.NONE == connPool.getConfiguration().getCompressionStrategy()) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.hset(key, field, value); } }.execute(key, OpName.HSET); } else { return new PipelineCompressionOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { return new PipelineLongResponse(null).apply(new Func0>() { @Override public Response call() { return jedisPipeline.hset(key, field, compressValue(value)); } }); } }.execute(key, OpName.HSET); } } @Override public Response hset(byte[] key, Map hash) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response hsetnx(final String key, final String field, final String value) { if (CompressionStrategy.NONE == connPool.getConfiguration().getCompressionStrategy()) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.hsetnx(key, field, value); } }.execute(key, OpName.HSETNX); } else { return new PipelineCompressionOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { return new PipelineLongResponse(null).apply(new Func0>() { @Override public Response call() { return jedisPipeline.hsetnx(key, field, compressValue(value)); } }); } }.execute(key, OpName.HSETNX); } } @Override public Response> hvals(final String key) { if (CompressionStrategy.NONE == connPool.getConfiguration().getCompressionStrategy()) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.hvals(key); } }.execute(key, OpName.HVALS); } else { return new PipelineCompressionOperation>() { @Override Response> execute(final Pipeline jedisPipeline) throws DynoException { return new PipelineListResponse(null).apply(new Func0>>() { @Override public Response> call() { return jedisPipeline.hvals(key); } }); } }.execute(key, OpName.HVALS); } } @Override public Response incr(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.incr(key); } }.execute(key, OpName.INCR); } @Override public Response incrBy(final String key, final long integer) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.incrBy(key, integer); } }.execute(key, OpName.INCRBY); } /* not supported by RedisPipeline 2.7.3 */ public Response incrByFloat(final String key, final double increment) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.incrByFloat(key, increment); } }.execute(key, OpName.INCRBYFLOAT); } @Override public Response psetex(String key, long milliseconds, String value) { return null; } @Override public Response lindex(final String key, final long index) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.lindex(key, index); } }.execute(key, OpName.LINDEX); } @Override public Response linsert(final String key, final ListPosition where, final String pivot, final String value) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.linsert(key, where, pivot, value); } }.execute(key, OpName.LINSERT); } @Override public Response llen(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.llen(key); } }.execute(key, OpName.LLEN); } @Override public Response lpop(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.lpop(key); } }.execute(key, OpName.LPOP); } @Override public Response lpush(final String key, final String... string) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.lpush(key, string); } }.execute(key, OpName.LPUSH); } @Override public Response lpushx(final String key, final String... string) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.lpushx(key, string); } }.execute(key, OpName.LPUSHX); } @Override public Response> lrange(final String key, final long start, final long end) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.lrange(key, start, end); } }.execute(key, OpName.LRANGE); } @Override public Response lrem(final String key, final long count, final String value) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.lrem(key, count, value); } }.execute(key, OpName.LREM); } @Override public Response lset(final String key, final long index, final String value) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.lset(key, index, value); } }.execute(key, OpName.LSET); } @Override public Response ltrim(final String key, final long start, final long end) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.ltrim(key, start, end); } }.execute(key, OpName.LTRIM); } @Override public Response move(final String key, final int dbIndex) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.move(key, dbIndex); } }.execute(key, OpName.MOVE); } @Override public Response persist(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.persist(key); } }.execute(key, OpName.PERSIST); } /* not supported by RedisPipeline 2.7.3 */ public Response rename(final String oldkey, final String newkey) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.rename(oldkey, newkey); } }.execute(oldkey, OpName.RENAME); } /* not supported by RedisPipeline 2.7.3 */ public Response renamenx(final String oldkey, final String newkey) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.renamenx(oldkey, newkey); } }.execute(oldkey, OpName.RENAMENX); } @Override public Response rpop(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.rpop(key); } }.execute(key, OpName.RPOP); } @Override public Response rpush(final String key, final String... string) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.rpush(key, string); } }.execute(key, OpName.RPUSH); } @Override public Response rpushx(final String key, final String... string) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.rpushx(key, string); } }.execute(key, OpName.RPUSHX); } @Override public Response sadd(final String key, final String... member) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.sadd(key, member); } }.execute(key, OpName.SADD); } @Override public Response scard(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.scard(key); } }.execute(key, OpName.SCARD); } @Override public Response sismember(final String key, final String member) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.sismember(key, member); } }.execute(key, OpName.SISMEMBER); } @Override public Response set(final String key, final String value) { if (CompressionStrategy.NONE == connPool.getConfiguration().getCompressionStrategy()) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { long startTime = System.nanoTime() / 1000; try { return jedisPipeline.set(key, value); } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordSendLatency(OpName.SET.name(), duration, TimeUnit.MICROSECONDS); } } }.execute(key, OpName.SET); } else { return new PipelineCompressionOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { long startTime = System.nanoTime() / 1000; try { return new PipelineResponse(null).apply(new Func0>() { @Override public Response call() { return jedisPipeline.set(key, compressValue(value)); } }); } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordSendLatency(OpName.SET.name(), duration, TimeUnit.MICROSECONDS); } } }.execute(key, OpName.SET); } } @Override public Response setbit(final String key, final long offset, final boolean value) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.setbit(key, offset, value); } }.execute(key, OpName.SETBIT); } @Override public Response setex(final String key, final int seconds, final String value) { if (CompressionStrategy.NONE == connPool.getConfiguration().getCompressionStrategy()) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.setex(key, seconds, value); } }.execute(key, OpName.SETEX); } else { return new PipelineCompressionOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { return new PipelineResponse(null).apply(new Func0>() { @Override public Response call() { return jedisPipeline.setex(key, seconds, compressValue(value)); } }); } }.execute(key, OpName.SETEX); } } @Override public Response setnx(final String key, final String value) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.setnx(key, value); } }.execute(key, OpName.SETNX); } @Override public Response setrange(final String key, final long offset, final String value) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.setrange(key, offset, value); } }.execute(key, OpName.SETRANGE); } @Override public Response> smembers(final String key) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.smembers(key); } }.execute(key, OpName.SMEMBERS); } @Override public Response> sort(final String key) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.sort(key); } }.execute(key, OpName.SORT); } @Override public Response> sort(final String key, final SortingParams sortingParameters) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.sort(key, sortingParameters); } }.execute(key, OpName.SORT); } @Override public Response spop(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.spop(key); } }.execute(key, OpName.SPOP); } @Override public Response> spop(final String key, final long count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response srandmember(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.srandmember(key); } }.execute(key, OpName.SRANDMEMBER); } @Override public Response srem(final String key, final String... member) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.srem(key, member); } }.execute(key, OpName.SREM); } /** * This method is not supported by the BinaryRedisPipeline interface. */ public Response> sscan(final String key, final int cursor) { throw new UnsupportedOperationException("'SSCAN' cannot be called in pipeline"); } /** * This method is not supported by the BinaryRedisPipeline interface. */ public Response> sscan(final String key, final String cursor) { throw new UnsupportedOperationException("'SSCAN' cannot be called in pipeline"); } @Override public Response strlen(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.strlen(key); } }.execute(key, OpName.STRLEN); } @Override public Response substr(final String key, final int start, final int end) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.substr(key, start, end); } }.execute(key, OpName.SUBSTR); } @Override public Response touch(String key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response ttl(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.ttl(key); } }.execute(key, OpName.TTL); } @Override public Response pttl(String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.pttl(key); } }.execute(key, OpName.PTTL); } @Override public Response type(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.type(key); } }.execute(key, OpName.TYPE); } @Override public Response zadd(final String key, final double score, final String member) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zadd(key, score, member); } }.execute(key, OpName.ZADD); } @Override public Response zadd(final String key, final Map scoreMembers) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zadd(key, scoreMembers); } }.execute(key, OpName.ZADD); } @Override public Response zcard(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zcard(key); } }.execute(key, OpName.ZCARD); } @Override public Response zcount(final String key, final double min, final double max) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zcount(key, min, max); } }.execute(key, OpName.ZCOUNT); } @Override public Response zcount(String key, String min, String max) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zcount(key, min, max); } }.execute(key, OpName.ZCOUNT); } @Override public Response zincrby(final String key, final double score, final String member) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zincrby(key, score, member); } }.execute(key, OpName.ZINCRBY); } @Override public Response> zrange(final String key, final long start, final long end) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrange(key, start, end); } }.execute(key, OpName.ZRANGE); } @Override public Response> zrangeByScore(final String key, final double min, final double max) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrangeByScore(key, min, max); } }.execute(key, OpName.ZRANGEBYSCORE); } @Override public Response> zrangeByScore(final String key, final String min, final String max) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrangeByScore(key, min, max); } }.execute(key, OpName.ZRANGEBYSCORE); } @Override public Response> zrangeByScore(final String key, final double min, final double max, final int offset, final int count) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrangeByScore(key, min, max, offset, count); } }.execute(key, OpName.ZRANGEBYSCORE); } @Override public Response> zrangeByScore(String key, String min, String max, int offset, int count) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrangeByScore(key, min, max, offset, count); } }.execute(key, OpName.ZRANGEBYSCORE); } @Override public Response> zrangeByScoreWithScores(final String key, final double min, final double max) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrangeByScoreWithScores(key, min, max); } }.execute(key, OpName.ZRANGEBYSCOREWITHSCORES); } @Override public Response> zrangeByScoreWithScores(final String key, final double min, final double max, final int offset, final int count) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrangeByScoreWithScores(key, min, max, offset, count); } }.execute(key, OpName.ZRANGEBYSCOREWITHSCORES); } @Override public Response> zrevrangeByScore(final String key, final double max, final double min) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrevrangeByScore(key, max, min); } }.execute(key, OpName.ZREVRANGEBYSCORE); } @Override public Response> zrevrangeByScore(final String key, final String max, final String min) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrevrangeByScore(key, max, min); } }.execute(key, OpName.ZREVRANGEBYSCORE); } @Override public Response> zrevrangeByScore(final String key, final double max, final double min, final int offset, final int count) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrevrangeByScore(key, max, min, offset, count); } }.execute(key, OpName.ZREVRANGEBYSCORE); } @Override public Response> zrevrangeByScore(String key, String max, String min, int offset, int count) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrevrangeByScore(key, max, min, offset, count); } }.execute(key, OpName.ZREVRANGEBYSCORE); } @Override public Response> zrevrangeByScoreWithScores(final String key, final double max, final double min) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrevrangeByScoreWithScores(key, max, min); } }.execute(key, OpName.ZREVRANGEBYSCOREWITHSCORES); } @Override public Response> zrevrangeByScoreWithScores(String key, String max, String min) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrevrangeByScoreWithScores(key, max, min); } }.execute(key, OpName.ZREVRANGEBYSCOREWITHSCORES); } @Override public Response> zrevrangeByScoreWithScores(final String key, final double max, final double min, final int offset, final int count) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrevrangeByScoreWithScores(key, max, min, offset, count); } }.execute(key, OpName.ZREVRANGEBYSCOREWITHSCORES); } @Override public Response> zrevrangeByScoreWithScores(String key, String max, String min, int offset, int count) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrevrangeByScoreWithScores(key, max, min, offset, count); } }.execute(key, OpName.ZREVRANGEBYSCOREWITHSCORES); } @Override public Response> zrangeWithScores(final String key, final long start, final long end) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrangeWithScores(key, start, end); } }.execute(key, OpName.ZRANGEWITHSCORES); } @Override public Response zrank(final String key, final String member) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrank(key, member); } }.execute(key, OpName.ZRANK); } @Override public Response zrem(final String key, final String... member) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrem(key, member); } }.execute(key, OpName.ZREM); } @Override public Response zremrangeByRank(final String key, final long start, final long end) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zremrangeByRank(key, start, end); } }.execute(key, OpName.ZREMRANGEBYRANK); } @Override public Response zremrangeByScore(final String key, final double start, final double end) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zremrangeByScore(key, start, end); } }.execute(key, OpName.ZREMRANGEBYSCORE); } @Override public Response zremrangeByScore(String key, String min, String max) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zremrangeByScore(key, min, max); } }.execute(key, OpName.ZREMRANGEBYSCORE); } @Override public Response> zrevrange(final String key, final long start, final long end) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrevrange(key, start, end); } }.execute(key, OpName.ZREVRANGE); } @Override public Response> zrevrangeWithScores(final String key, final long start, final long end) { return new PipelineOperation>() { @Override Response> execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrevrangeWithScores(key, start, end); } }.execute(key, OpName.ZREVRANGEWITHSCORES); } @Override public Response zrevrank(final String key, final String member) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zrevrank(key, member); } }.execute(key, OpName.ZREVRANK); } @Override public Response zscore(final String key, final String member) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zscore(key, member); } }.execute(key, OpName.ZSCORE); } /** * This method is not supported by the BinaryRedisPipeline interface. */ public Response> zscan(final String key, final int cursor) { throw new UnsupportedOperationException("'ZSCAN' cannot be called in pipeline"); } @Override public Response zlexcount(String key, String min, String max) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrangeByLex(String key, String min, String max) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrangeByLex(String key, String min, String max, int offset, int count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zremrangeByLex(String key, String start, String end) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response bitcount(final String key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.bitcount(key); } }.execute(key, OpName.BITCOUNT); } @Override public Response bitcount(final String key, final long start, final long end) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.bitcount(key, start, end); } }.execute(key, OpName.BITCOUNT); } /**** Binary Operations ****/ @Override public Response set(final byte[] key, final byte[] value) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { long startTime = System.nanoTime() / 1000; try { return jedisPipeline.set(key, value); } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordSendLatency(OpName.SET.name(), duration, TimeUnit.MICROSECONDS); } } }.execute(key, OpName.SET); } @Override public Response pfadd(String key, String... elements) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response pfcount(String key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> bitfield(String key, String... arguments) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response hstrlen(String key, String field) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.hstrlen(key, field); } }.execute(key, OpName.HSTRLEN); } @Override public Response dump(String key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response restore(String key, int ttl, byte[] serializedValue) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response restoreReplace(String key, int ttl, byte[] serializedValue) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response migrate(String host, int port, String key, int destinationDB, int timeout) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrevrangeByLex(String key, String max, String min) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrevrangeByLex(String key, String max, String min, int offset, int count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response geoadd(String arg0, Map arg1) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response geoadd(String arg0, double arg1, double arg2, String arg3) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response geodist(String arg0, String arg1, String arg2) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response geodist(String arg0, String arg1, String arg2, GeoUnit arg3) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> geohash(String arg0, String... arg1) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> geopos(String arg0, String... arg1) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadius(String arg0, double arg1, double arg2, double arg3, GeoUnit arg4) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadiusReadonly(String key, double longitude, double latitude, double radius, GeoUnit unit) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadius(String arg0, double arg1, double arg2, double arg3, GeoUnit arg4, GeoRadiusParam arg5) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadiusReadonly(String key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadiusByMember(String arg0, String arg1, double arg2, GeoUnit arg3) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadiusByMemberReadonly(String key, String member, double radius, GeoUnit unit) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadiusByMember(String arg0, String arg1, double arg2, GeoUnit arg3, GeoRadiusParam arg4) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadiusByMemberReadonly(String key, String member, double radius, GeoUnit unit, GeoRadiusParam param) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response bitpos(String key, boolean value) { return null; } @Override public Response bitpos(String key, boolean value, BitPosParams params) { return null; } @Override public Response set(String key, String value, SetParams params) { return null; } @Override public Response> srandmember(String key, int count) { return null; } @Override public Response> zrangeByScoreWithScores(String key, String min, String max) { return null; } @Override public Response> zrangeByScoreWithScores(String key, String min, String max, int offset, int count) { return null; } @Override public Response objectRefcount(String key) { return null; } @Override public Response objectEncoding(String key) { return null; } @Override public Response objectIdletime(String key) { return null; } @Override public Response zadd(String key, Map members, ZAddParams params) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zadd(key, members, params); } }.execute(key, OpName.ZADD); } public Response zadd(final String key, final double score, final String member, final ZAddParams params) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.zadd(key, score, member, params); } }.execute(key, OpName.ZADD); } @Override public Response zincrby(String arg0, double arg1, String arg2, ZIncrByParams arg3) { throw new UnsupportedOperationException("not yet implemented"); } public void sync() { long startTime = System.nanoTime() / 1000; try { jedisPipeline.sync(); opMonitor.recordPipelineSync(); } catch (JedisConnectionException jce) { String msg = "Failed sync() to host: " + getHostInfo(); pipelineEx.set(new FatalConnectionException(msg, jce). setHost(connection == null ? Host.NO_HOST : connection.getHost())); cpMonitor.incOperationFailure(connection == null ? null : connection.getHost(), jce); throw jce; } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordLatency(duration, TimeUnit.MICROSECONDS); discardPipeline(false); releaseConnection(); } } public List syncAndReturnAll() { long startTime = System.nanoTime() / 1000; try { List result = jedisPipeline.syncAndReturnAll(); opMonitor.recordPipelineSync(); return result; } catch (JedisConnectionException jce) { String msg = "Failed syncAndReturnAll() to host: " + getHostInfo(); pipelineEx.set(new FatalConnectionException(msg, jce). setHost(connection == null ? Host.NO_HOST : connection.getHost())); cpMonitor.incOperationFailure(connection == null ? null : connection.getHost(), jce); throw jce; } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordLatency(duration, TimeUnit.MICROSECONDS); discardPipeline(false); releaseConnection(); } } private void discardPipeline(boolean recordLatency) { try { if (jedisPipeline != null) { long startTime = System.nanoTime() / 1000; jedisPipeline.sync(); if (recordLatency) { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordLatency(duration, TimeUnit.MICROSECONDS); } jedisPipeline = null; } } catch (Exception e) { Logger.warn(String.format("Failed to discard jedis pipeline, %s", getHostInfo()), e); } } private void releaseConnection() { if (connection != null) { try { connection.getContext().reset(); connection.getParentConnectionPool().returnConnection(connection); if (pipelineEx.get() != null) { connPool.getHealthTracker().trackConnectionError(connection.getParentConnectionPool(), pipelineEx.get()); pipelineEx.set(null); } connection = null; } catch (Exception e) { Logger.warn(String.format("Failed to return connection in Dyno Jedis Pipeline, %s", getHostInfo()), e); } } } public void discardPipelineAndReleaseConnection() { opMonitor.recordPipelineDiscard(); discardPipeline(true); releaseConnection(); } @Override public void close() throws Exception { discardPipelineAndReleaseConnection(); } private String getHostInfo() { if (connection != null && connection.getHost() != null) { return connection.getHost().toString(); } return "unknown"; } @Override public Response append(byte[] key, byte[] value) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> blpop(byte[] arg) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> brpop(byte[] arg) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response decr(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response decrBy(final byte[] key, final long integer) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.decrBy(key, integer); } }.execute(key, OpName.DECRBY); } @Override public Response del(final byte[] key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.del(key); } }.execute(key, OpName.DEL); } @Override public Response unlink(byte[] keys) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.unlink(keys); } }.execute(keys, OpName.UNLINK); } @Override public Response echo(byte[] string) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response exists(final byte[] key) { return new PipelineOperation() { @Override Response execute(final Pipeline jedisPipeline) throws DynoException { return jedisPipeline.exists(key); } }.execute(key, OpName.EXISTS); } @Override public Response expire(byte[] key, int seconds) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response pexpire(byte[] key, long milliseconds) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response expireAt(byte[] key, long unixTime) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response pexpireAt(byte[] key, long millisecondsTimestamp) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response get(final byte[] key) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { long startTime = System.nanoTime() / 1000; try { return jedisPipeline.get(key); } finally { long duration = System.nanoTime() / 1000 - startTime; opMonitor.recordSendLatency(OpName.GET.name(), duration, TimeUnit.MICROSECONDS); } } }.execute(key, OpName.GET); } @Override public Response getbit(byte[] key, long offset) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response getSet(final byte[] key, final byte[] value) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.getSet(key, value); } }.execute(key, OpName.GETSET); } @Override public Response getrange(byte[] key, long startOffset, long endOffset) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response hdel(byte[] key, byte[]... field) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response hexists(byte[] key, byte[] field) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response hincrBy(byte[] key, byte[] field, long value) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> hkeys(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response hlen(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response hsetnx(byte[] key, byte[] field, byte[] value) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> hvals(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response incr(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response incrBy(byte[] key, long integer) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response lindex(byte[] key, long index) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response linsert(byte[] key, ListPosition where, byte[] pivot, byte[] value) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response llen(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response lpop(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response lpush(byte[] key, byte[]... string) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response lpushx(byte[] key, byte[]... bytes) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> lrange(byte[] key, long start, long end) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response lrem(byte[] key, long count, byte[] value) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response lset(byte[] key, long index, byte[] value) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response ltrim(byte[] key, long start, long end) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response move(byte[] key, int dbIndex) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response persist(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response rpop(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response rpush(byte[] key, byte[]... string) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response rpushx(byte[] key, byte[]... string) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response sadd(byte[] key, byte[]... member) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response scard(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response setbit(byte[] key, long offset, byte[] value) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response setrange(byte[] key, long offset, byte[] value) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response setex(final byte[] key, final int seconds, final byte[] value) { return new PipelineOperation() { @Override Response execute(Pipeline jedisPipeline) throws DynoException { return jedisPipeline.setex(key, seconds, value); } }.execute(key, OpName.SETEX); } @Override public Response setnx(byte[] key, byte[] value) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> smembers(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response sismember(byte[] key, byte[] member) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> sort(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> sort(byte[] key, SortingParams sortingParameters) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response spop(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> spop(byte[] key, long count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response srandmember(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response srem(byte[] key, byte[]... member) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response strlen(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response substr(byte[] key, int start, int end) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response touch(byte[] keys) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response ttl(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response pttl(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response type(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zadd(byte[] key, double score, byte[] member) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zadd(byte[] key, double score, byte[] member, ZAddParams params) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zadd(byte[] key, Map scoreMembers) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zadd(byte[] key, Map scoreMembers, ZAddParams params) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zcard(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zcount(byte[] key, double min, double max) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zcount(byte[] key, byte[] min, byte[] max) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zincrby(byte[] key, double score, byte[] member) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zincrby(byte[] key, double score, byte[] member, ZIncrByParams params) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrange(byte[] key, long start, long end) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrangeByScore(byte[] key, double min, double max) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrangeByScore(byte[] key, byte[] min, byte[] max) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrangeByScore(byte[] key, double min, double max, int offset, int count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrangeByScore(byte[] key, byte[] min, byte[] max, int offset, int count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrangeByScoreWithScores(byte[] key, double min, double max) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrangeByScoreWithScores(byte[] key, byte[] min, byte[] max) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrangeByScoreWithScores(byte[] key, double min, double max, int offset, int count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrangeByScoreWithScores(byte[] key, byte[] min, byte[] max, int offset, int count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrevrangeByScore(byte[] key, double max, double min) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrevrangeByScore(byte[] key, byte[] max, byte[] min) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrevrangeByScore(byte[] key, double max, double min, int offset, int count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrevrangeByScore(byte[] key, byte[] max, byte[] min, int offset, int count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrevrangeByScoreWithScores(byte[] key, double max, double min) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrevrangeByScoreWithScores(byte[] key, byte[] max, byte[] min) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrevrangeByScoreWithScores(byte[] key, double max, double min, int offset, int count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrevrangeByScoreWithScores(byte[] key, byte[] max, byte[] min, int offset, int count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrangeWithScores(byte[] key, long start, long end) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zrank(byte[] key, byte[] member) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zrem(byte[] key, byte[]... member) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zremrangeByRank(byte[] key, long start, long end) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zremrangeByScore(byte[] key, double start, double end) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zremrangeByScore(byte[] key, byte[] start, byte[] end) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrevrange(byte[] key, long start, long end) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrevrangeWithScores(byte[] key, long start, long end) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zrevrank(byte[] key, byte[] member) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zscore(byte[] key, byte[] member) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zlexcount(byte[] key, byte[] min, byte[] max) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrangeByLex(byte[] key, byte[] min, byte[] max) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrangeByLex(byte[] key, byte[] min, byte[] max, int offset, int count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrevrangeByLex(byte[] key, byte[] max, byte[] min) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> zrevrangeByLex(byte[] key, byte[] max, byte[] min, int offset, int count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response zremrangeByLex(byte[] key, byte[] min, byte[] max) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response bitcount(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response bitcount(byte[] key, long start, long end) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response pfadd(byte[] key, byte[]... elements) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response pfcount(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response dump(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response restore(byte[] key, int ttl, byte[] serializedValue) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response restoreReplace(byte[] key, int ttl, byte[] serializedValue) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response migrate(String host, int port, byte[] key, int destinationDB, int timeout) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response geoadd(byte[] key, double longitude, double latitude, byte[] member) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response geoadd(byte[] key, Map memberCoordinateMap) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response geodist(byte[] key, byte[] member1, byte[] member2) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response geodist(byte[] key, byte[] member1, byte[] member2, GeoUnit unit) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> geohash(byte[] key, byte[]... members) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> geopos(byte[] key, byte[]... members) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadiusReadonly(byte[] key, double longitude, double latitude, double radius, GeoUnit unit) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadiusReadonly(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadiusByMemberReadonly(byte[] key, byte[] member, double radius, GeoUnit unit) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> georadiusByMemberReadonly(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> bitfield(byte[] key, byte[]... elements) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response hstrlen(byte[] key, byte[] field) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response bitpos(byte[] key, boolean value) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response bitpos(byte[] key, boolean value, BitPosParams params) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response set(byte[] key, byte[] value, SetParams params) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response> srandmember(byte[] key, int count) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response objectRefcount(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response objectEncoding(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response objectIdletime(byte[] key) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response incrByFloat(byte[] key, double increment) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response psetex(byte[] key, long milliseconds, byte[] value) { throw new UnsupportedOperationException("not yet implemented"); } @Override public Response hincrByFloat(byte[] key, byte[] field, double increment) { throw new UnsupportedOperationException("not yet implemented"); } }