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

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

/*******************************************************************************
 * Copyright 2011 Netflix
 *
 * 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 java.util.concurrent.TimeUnit;

import org.apache.commons.lang.NotImplementedException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisConnectionException;

import com.netflix.dyno.connectionpool.AsyncOperation;
import com.netflix.dyno.connectionpool.Connection;
import com.netflix.dyno.connectionpool.ConnectionContext;
import com.netflix.dyno.connectionpool.ConnectionFactory;
import com.netflix.dyno.connectionpool.ConnectionObservor;
import com.netflix.dyno.connectionpool.Host;
import com.netflix.dyno.connectionpool.HostConnectionPool;
import com.netflix.dyno.connectionpool.ListenableFuture;
import com.netflix.dyno.connectionpool.Operation;
import com.netflix.dyno.connectionpool.OperationMonitor;
import com.netflix.dyno.connectionpool.OperationResult;
import com.netflix.dyno.connectionpool.exception.DynoConnectException;
import com.netflix.dyno.connectionpool.exception.DynoException;
import com.netflix.dyno.connectionpool.exception.FatalConnectionException;
import com.netflix.dyno.connectionpool.exception.ThrottledException;
import com.netflix.dyno.connectionpool.impl.ConnectionContextImpl;
import com.netflix.dyno.connectionpool.impl.OperationResultImpl;

public class JedisConnectionFactory implements ConnectionFactory {

    private static final org.slf4j.Logger Logger = LoggerFactory.getLogger(JedisConnectionFactory.class);

	private final OperationMonitor opMonitor; 
	
	public JedisConnectionFactory(OperationMonitor monitor) {
		this.opMonitor = monitor;
	}
	
	@Override
	public Connection createConnection(HostConnectionPool pool, ConnectionObservor connectionObservor)
			throws DynoConnectException, ThrottledException {
		
		return new JedisConnection(pool);
	}

	public class JedisConnection implements Connection {

		private final HostConnectionPool hostPool;
		private final Jedis jedisClient; 
		private final ConnectionContextImpl context = new ConnectionContextImpl();
		
		private DynoConnectException lastDynoException;
		
		public JedisConnection(HostConnectionPool hostPool) {
			this.hostPool = hostPool;
			Host host = hostPool.getHost();
			jedisClient = new Jedis(host.getHostName(), host.getPort(), hostPool.getConnectionTimeout());
		}
		
		@Override
		public  OperationResult execute(Operation op) throws DynoException {
			
			long startTime = System.nanoTime()/1000;
			String opName = op.getName();

			OperationResultImpl opResult = null;
			
			try { 
				R result = op.execute(jedisClient, context);
				if (context.hasMetadata("compression") || context.hasMetadata("decompression")) {
                    opMonitor.recordSuccess(opName, true);
                } else {
                    opMonitor.recordSuccess(opName);
                }
				opResult = new OperationResultImpl(opName, result, opMonitor);
				opResult.addMetadata("connectionId", String.valueOf(this.hashCode()));
                return opResult;
				
			} catch (JedisConnectionException ex) {
                Logger.warn("Caught JedisConnectionException: " + ex.getMessage());
				opMonitor.recordFailure(opName, ex.getMessage());
				lastDynoException = (DynoConnectException) new FatalConnectionException(ex).setAttempt(1);
				throw lastDynoException;

			} catch (RuntimeException ex) {
                Logger.warn("Caught RuntimeException: " + ex.getMessage());
				opMonitor.recordFailure(opName, ex.getMessage());
				lastDynoException = (DynoConnectException) new FatalConnectionException(ex).setAttempt(1);
				throw lastDynoException;

			} finally {
				long duration = System.nanoTime()/1000 - startTime;
				if (opResult != null) {
					opResult.setLatency(duration, TimeUnit.MICROSECONDS);
				}
			}
		}

		@Override
		public  ListenableFuture> executeAsync(AsyncOperation op) throws DynoException {
			throw new NotImplementedException();
		}

		@Override
		public void close() {
			jedisClient.quit();
			jedisClient.disconnect();
		}

		@Override
		public Host getHost() {
			return hostPool.getHost();
		}

		@Override
		public void open() throws DynoException {
			jedisClient.connect();
		}

		@Override
		public DynoConnectException getLastException() {
			return lastDynoException;
		}

		@Override
		public HostConnectionPool getParentConnectionPool() {
			return hostPool;
		}

		@Override
		public void execPing() {
			String result = jedisClient.ping();
			if (result == null || result.isEmpty()) {
				throw new DynoConnectException("Unsuccessful ping, got empty result");
			}
		}

		@Override
		public ConnectionContext getContext() {
			return context;
		}
		
		public Jedis getClient() {
			return jedisClient;
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy