Search code examples
javacachingmicroservicesgoogle-guava-cache

How to pass two pass one more parameter other than key in google guava cache


I have create a cache using google guava cache

here is my implementation of it

private final LoadingCache<Long, DistChannel> channelServiceCache = CacheBuilder.newBuilder().maximumSize(50)
        .refreshAfterWrite(4, TimeUnit.HOURS).build(new CacheLoader<Long, DistChannel>() {

            @Override
            public DistChannel load(Long channelId) throws InvalidRequestException, TException {
                long start = System.nanoTime();
                try {
                    return channelService.getDistributionChannelById(channelId, SOLR_API_KEY);
                } catch (InvalidRequestException e) {
                    log.error("Cannot look up channel: {}", channelId, e);
                    String serviceName = StringUtils.isNotBlank(e.getServiceName()) ? e.getServiceName() : CHANNEL_SERVICE;
                    throw e.setServiceName(serviceName + "." + SERVICE_NAME + "." + hostName);
                } finally {
                    log.info("Channel Service call, ChannelId: {} Time : {}", channelId,
                            TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start));
                }
            }


            @Override
            public ListenableFuture<DistChannel> reload(final Long channelId, final DistChannel oldValue) throws Exception {
                ListenableFutureTask<DistChannel> task = ListenableFutureTask.create(new Callable<DistChannel>() {
                    public DistChannel call() {
                        long start = System.nanoTime();
                        try {
                            return channelService.getDistributionChannelById(channelId, SOLR_API_KEY);
                        } catch (TException e) {
                            log.error("Cannot look up channel: {}", channelId, e);
                        }finally {
                            log.info("reload Channel Service call, ChannelId: {} Time : {}", channelId,
                                    TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start));
                        }
                        return oldValue;
                    }
                });
                executorServiceForCache.execute(task);
                return task;
            }

        });

now in channelService.getDistributionChannelById method, I need to paas two values namely channelId and apiKey.

Currently its working fine as apiKey is constant. But now apiKey is modified to this contant ~ timestamp. for example:

SOLR_API_KEY~123456789

So My Problem is:

How can I pass one more parameter in channelServiceCache.get(key, extraparam here) without modifying the key.

Thing which I tried : I created a Key object in which my actual key as well as apiKey will be present and pass that as key in channelServiceCache But this will kill the purpose of cache as every kill will be considered a new key as it contains timestamp in apikey.

Is there any way I can do this with google guava?

EDIT : One more thing which I missed:

service will give same output for same channelId, API key is only used for authentication and logging and monitoring request counts. But I guess it makes sense, If I can serve next request with same channelID from cache, then apiKey will never be passed to actual service (where actual logging and monitoring is taking place.) Is there any other way to implement this functionality without actually killing purpose of google guava.


Solution

  • If the output of the service is different for each channel id and API Key, then the API key needs to be part of the cache key.

    If the output is identical no matter what API key, then you can use any API key or the always the same API key.

    Passing down the API key from the caller, but caching the value does make no sense, or is essentially identically to randomly choose an API key. As soon as the value is in the cache, you will return a result that was retrieved with a different API key from the previous caller.