Guava cache not taking values from cache and refreshing for every call

555 views Asked by At

I have created cache in my spark application, to refresh few values after every 6 hours.

The code looks as below.

val cachedList: Cache[String, String] = CacheBuilder.newBuilder()
    .maximumSize(10)
    .expireAfterWrite(refreshTimeInSeconds.toLong, TimeUnit.SECONDS)
    .build()

This method gets the items and caches for me.

  def prepareUnfilteredAccountList(): Array[String] = {
    logger.info("Refreshing the UNFILTERED Accounts List from API")
    val unfilteredAccounts = apiService.getElementsToCache().get.map(_.accountNumber).toArray
    logger.trace("cached list has been refreshed New List is " +

    unfilteredAccounts
  }

This method is used to get the cached values into list.

def getUnfilteredList(): Array[String] = {
    unfilteredAccounts.get("cached_list", new Callable[String]() {
      override def call(): String = {
        prepareUnfilteredAccountList().mkString(",")
      }
    }).split(",")
  }

However, i observed that the cache is getting refreshed for every call, instead of getting refreshed after specified time period.

1

There are 1 answers

0
dimo414 On

First off, if you want to store a list or an array in a Cache you can do so, there's no need to convert it into a string and then split it back into an array.

Second, maximumSize() configures how many entries are in your cache - by the looks of it your cache only ever has one entry (your list), so specifying a maximum size is meaningless.

Third, if you're only trying to cache one value you might prefer the Suppliers.memoizeWithExperiation() API, which is simpler and less expensive than a Cache.

Fourth, in prepareUnfilteredAccountList() unfilteredAccounts appears to be an array, but in getUnfilteredList() the same variable appears to be a cache. At best this is going to be confusing for you to work with. Use distinct variable names for distinct purposes. It's possible this is the cause of your problems.

All that said calling Cache.get(K, Runnable) should work as you expect - it will invoke the Runnable only if the given key does not already exist in the the cache and has not expired. If that isn't the behavior you're seeing the bug is likely elsewhere in your code. Perhaps your refreshTimeInSeconds is not what you expect, or you're not actually reading the value you're caching, or the cache is actually working as intended and you're misdiagnosing its behavior as erroneous.