From 8e03d38f0c4d687162e8be1b9bbf660ed210d8f9 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 9 Sep 2015 14:25:31 +0200 Subject: VCache und thrift --- .../org/openslx/thrifthelper/ThriftHandler.java | 24 +++--- .../org/openslx/thrifthelper/ThriftManager.java | 28 +++---- .../java/org/openslx/util/GenericDataCache.java | 87 ++++++++++++++-------- 3 files changed, 77 insertions(+), 62 deletions(-) diff --git a/src/main/java/org/openslx/thrifthelper/ThriftHandler.java b/src/main/java/org/openslx/thrifthelper/ThriftHandler.java index 01ed0b0..760220a 100644 --- a/src/main/java/org/openslx/thrifthelper/ThriftHandler.java +++ b/src/main/java/org/openslx/thrifthelper/ThriftHandler.java @@ -60,25 +60,13 @@ class ThriftHandler implements InvocationHandler // first find the thrift methods if ( !thriftMethods.contains( method.getName() ) ) { - try { - return method.invoke( getClient(), args ); - } catch ( InvocationTargetException e ) { - Throwable cause = e.getCause(); - if ( cause == null ) { - cause = e; - } - throw cause; - } + throw new IllegalAccessException( "Cannot call this method on a proxied thrift client" ); } T client = getClient(); try { Throwable cause = null; for ( int i = 1;; i++ ) { - if ( client == null ) { - LOGGER.debug( "Transport error - re-initialising ..." ); - client = getClient(); - } if ( client != null ) { try { return method.invoke( client, args ); @@ -89,14 +77,19 @@ class ThriftHandler implements InvocationHandler } freeClient( client ); client = null; - if ( cause == null ) + if ( cause == null ) { cause = e; + } } } // Call the error callback. As long as true is returned, keep retrying if ( !errorCallback.thriftError( i, method.getName(), cause ) ) { break; } + if ( client == null ) { + client = getClient(); + cause = null; + } } // Uh oh @@ -126,8 +119,9 @@ class ThriftHandler implements InvocationHandler T client; synchronized ( pool ) { client = pool.poll(); - if ( client != null ) + if ( client != null ) { return client; + } } // Pool is closed, create new client LOGGER.debug( "Creating new thrift client" ); diff --git a/src/main/java/org/openslx/thrifthelper/ThriftManager.java b/src/main/java/org/openslx/thrifthelper/ThriftManager.java index c276034..7fc6aa7 100644 --- a/src/main/java/org/openslx/thrifthelper/ThriftManager.java +++ b/src/main/java/org/openslx/thrifthelper/ThriftManager.java @@ -5,6 +5,7 @@ import java.lang.reflect.Proxy; import java.net.InetSocketAddress; import java.net.Socket; +import javax.net.SocketFactory; import javax.net.ssl.SSLContext; import org.apache.log4j.Logger; @@ -193,23 +194,22 @@ public class ThriftManager { try { TSocket tsock; - if ( ctx == null ) { - tsock = new TSocket( host, port, timeout ); - tsock.open(); - } else { - Socket socket = null; - try { + Socket socket = null; + try { + if ( ctx == null ) { + socket = SocketFactory.getDefault().createSocket(); + } else { socket = ctx.getSocketFactory().createSocket(); - socket.setSoTimeout( timeout ); - socket.connect( new InetSocketAddress( host, port ), timeout ); - } catch ( IOException e ) { - if ( socket != null ) { - Util.safeClose( socket ); - } - throw new TTransportException(); } - tsock = new TSocket( socket ); + socket.connect( new InetSocketAddress( host, port ), 4000 ); + socket.setSoTimeout( timeout ); + } catch ( IOException e ) { + if ( socket != null ) { + Util.safeClose( socket ); + } + throw new TTransportException(); } + tsock = new TSocket( socket ); return new TBinaryProtocol( new TFramedTransport( tsock ) ); } catch ( TTransportException e ) { LOGGER.error( "Could not open transport to thrift server at " + host + ":" + port ); diff --git a/src/main/java/org/openslx/util/GenericDataCache.java b/src/main/java/org/openslx/util/GenericDataCache.java index 5852c94..5ae73fb 100644 --- a/src/main/java/org/openslx/util/GenericDataCache.java +++ b/src/main/java/org/openslx/util/GenericDataCache.java @@ -4,90 +4,111 @@ import java.util.concurrent.atomic.AtomicReference; import org.apache.log4j.Logger; -public abstract class GenericDataCache { - - private static final Logger LOGGER = Logger.getLogger(GenericDataCache.class); - +public abstract class GenericDataCache +{ + + private static final Logger LOGGER = Logger.getLogger( GenericDataCache.class ); + /** * How long the cached data is valid after fetching */ private final int validMs; - + /** * Deadline when the cache goes invalid */ private long validUntil = 0; - + /** * The data being held */ private final AtomicReference item = new AtomicReference<>(); - - public GenericDataCache(int validMs) { + + public GenericDataCache( int validMs ) + { this.validMs = validMs; } - + /** * Get the cached object, but refresh the cache first if * the cached instance is too old. * * @return */ - public T get() { - return get(CacheMode.DEFAULT); + public T get() + { + return get( CacheMode.DEFAULT ); } - + /** * Get the cached object, using the given cache access strategy. * ALWAYS_CACHED: Never refresh the cache, except if it has never been fetched before * DEFAULT: Only fetch from remote if the cached value is too old * NEVER_CACHED: Always fetch from remote. If it fails, return null - * - * @param mode Cache access strategy as described above + * + * @param mode Cache access strategy as described above * @return T */ - public T get(CacheMode mode) { - switch (mode) { - case ALWAYS_CACHED: - if (validUntil == 0) - ensureUpToDate(true); + public T get( CacheMode mode ) + { + switch ( mode ) { + case FORCE_CACHED: + break; + case PREFER_CACHED: + if ( validUntil == 0 ) + ensureUpToDate( true ); break; case DEFAULT: - ensureUpToDate(false); + ensureUpToDate( false ); break; case NEVER_CACHED: - if (!ensureUpToDate(true)) + if ( !ensureUpToDate( true ) ) return null; break; } return item.get(); } - - private synchronized boolean ensureUpToDate(boolean force) { + + private synchronized boolean ensureUpToDate( boolean force ) + { final long now = System.currentTimeMillis(); - if (!force && now < validUntil) + if ( !force && now < validUntil ) return true; T fetched; try { fetched = update(); - if (fetched == null) + if ( fetched == null ) return false; - } catch (Exception e) { - LOGGER.warn("Could not fetch fresh data", e); + } catch ( Exception e ) { + LOGGER.warn( "Could not fetch fresh data", e ); return false; } - item.set(fetched); + item.set( fetched ); validUntil = now + validMs; return true; } - + protected abstract T update() throws Exception; - + // - - public static enum CacheMode { - ALWAYS_CACHED, + + public static enum CacheMode + { + /** + * Use cache, even if the item has never been fetched before. + */ + FORCE_CACHED, + /** + * Use cache if it's not empty, no matter how old it is. + */ + PREFER_CACHED, + /** + * Obey the cache timeout value of this cache. + */ DEFAULT, + /** + * Always fetch a fresh instance of the item. + */ NEVER_CACHED } -- cgit v1.2.3-55-g7522