public T get()

in evcache-core/src/main/java/com/netflix/evcache/EVCacheImpl.java [1056:1134]


    public <T> T get(String key, Transcoder<T> tc, Policy policy) throws EVCacheException {
        if (null == key) throw new IllegalArgumentException();

        final boolean throwExc = doThrowException();
        final EVCacheClient[] clients = _pool.getEVCacheClientForWrite();
        if (clients.length == 0) {
            incrementFastFail(EVCacheMetricsFactory.NULL_CLIENT, Call.GET);
            if (throwExc) throw new EVCacheException("Could not find a client to asynchronously get the data");
            return null; // Fast failure
        }

        final int expectedSuccessCount = policyToCount(policy, clients.length);
        if(expectedSuccessCount <= 1) return get(key, tc);

        final long startTime = EVCacheMetricsFactory.getInstance().getRegistry().clock().wallTime();
        String status = EVCacheMetricsFactory.SUCCESS;
        String cacheOperation = EVCacheMetricsFactory.YES;
        int tries = 1;
        try {
            final List<Future<T>> futureList = new ArrayList<Future<T>>(clients.length);
            final long endTime = startTime + _pool.getReadTimeout().get().intValue();
            for (EVCacheClient client : clients) {
                final Future<T> future = getGetFuture(client, key, tc, throwExc);
                futureList.add(future);
                if (log.isDebugEnabled() && shouldLog()) log.debug("GET : CONSISTENT : APP " + _appName + ", Future " + future + " for key : " + key + " with policy : " + policy + " for client : " + client);
            }

            final Map<T, List<EVCacheClient>> evcacheClientMap = new HashMap<T, List<EVCacheClient>>();
            //final Map<T, Integer> tMap = new HashMap<T,Integer>();
            if (log.isDebugEnabled() && shouldLog()) log.debug("GET : CONSISTENT : Total Requests " + clients.length + "; Expected Success Count : " + expectedSuccessCount);
            for(Future<T> future : futureList) {
                try {
                    if(future instanceof EVCacheOperationFuture) {
                        EVCacheOperationFuture<T> evcacheOperationFuture = (EVCacheOperationFuture<T>)future;
                        long duration = endTime - System.currentTimeMillis();
                        if(duration < 20) duration = 20;
                        if (log.isDebugEnabled() && shouldLog()) log.debug("GET : CONSISTENT : block duration : " + duration);
                        final T t = evcacheOperationFuture.get(duration, TimeUnit.MILLISECONDS, throwExc, false);
                        if (log.isTraceEnabled() && shouldLog()) log.trace("GET : CONSISTENT : value : " + t);
                        if(t != null) {
                            final List<EVCacheClient> cList = evcacheClientMap.computeIfAbsent(t, k -> new ArrayList<EVCacheClient>(clients.length));
                            cList.add(evcacheOperationFuture.getEVCacheClient());
                            if (log.isDebugEnabled() && shouldLog()) log.debug("GET : CONSISTENT : Added Client to ArrayList " + cList);
                        }
                    }
                } catch (Exception e) {
                    log.error("Exception",e);
                }
            }
            T retVal = null;
             /* TODO : use metaget to get TTL and set it. For now we will delete the inconsistent value */
            for(Entry<T, List<EVCacheClient>> entry : evcacheClientMap.entrySet()) {
                if (log.isDebugEnabled() && shouldLog()) log.debug("GET : CONSISTENT : Existing Count for Value : " + entry.getValue().size() + "; expectedSuccessCount : " + expectedSuccessCount);
                if(entry.getValue().size() >= expectedSuccessCount) {
                    retVal = entry.getKey();
                } else {
                    for(EVCacheClient client : entry.getValue()) {
                        if (log.isDebugEnabled() && shouldLog()) log.debug("GET : CONSISTENT : Delete in-consistent vale from : " + client);
                        client.delete(key);
                    }
                }
            }
            if(retVal != null) {
                if (log.isDebugEnabled() && shouldLog()) log.debug("GET : CONSISTENT : policy : " + policy + " was met. Will return the value. Total Duration : " + (System.currentTimeMillis() - startTime) + " milli Seconds.");
                return retVal;
            }
            if (log.isDebugEnabled() && shouldLog()) log.debug("GET : CONSISTENT : policy : " + policy + " was NOT met. Will return NULL. Total Duration : " + (System.currentTimeMillis() - startTime) + " milli Seconds.");
            return null;
        } catch (Exception ex) {
            status = EVCacheMetricsFactory.ERROR;
            if (!throwExc) return null;
            throw new EVCacheException("Exception getting data for APP " + _appName + ", key = " + key, ex);
        } finally {
            final long duration = EVCacheMetricsFactory.getInstance().getRegistry().clock().wallTime()- startTime;
            getTimer(Call.GET_ALL.name(), EVCacheMetricsFactory.READ, cacheOperation, status, tries, maxReadDuration.get().intValue(), null).record(duration, TimeUnit.MILLISECONDS);
            if (log.isDebugEnabled() && shouldLog()) log.debug("GET : CONSISTENT : APP " + _appName + ", Took " + duration + " milliSec.");
        }

    }