2

I am new to Guava and I want to return comma separated list of users essentially a String. I am using one third party API to fetch the list. I want to cache that list and return that entire list if user queries.

I looked at few examples online and they use LoadingCache<k, v> and CacheLoader<k,v>. I do not have any second argument and usernames are unique. Our application is not going to support individual querying on the user

Is there any flavor of / I can twik LoadingCache which will allow me to do that? Something like

LoadingCache<String> 
.. some code .. 
CacheLoader<String> { 
/*populate comma separated list_of_users if not in cache*/ 
return list_of_users
}
Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
  • You have two close votes "unclear what you're asking", partly because your example code isn't even close to valid Java, and partly because you've not explained what you want your cache to do. Try at least providing an example of how you'd like to interact with the class you're writing, and expected results. (If it looks like fragments of jUnit test, you're on the right track) – slim Dec 16 '16 at 16:34

1 Answers1

4

As you've no doubt seen, the pattern for a LoadingCache is:

 LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
   .maximumSize(1000)
   .expireAfterWrite(10, TimeUnit.MINUTES)
   // ... other configuration builder methods ...
   .build(
       new CacheLoader<Key, Graph>() {
         public Graph load(Key key) throws AnyException {
           return createExpensiveGraph(key);
         }
       });

If your service doesn't take a key, then you could just ignore it, or use a constant.

 LoadingCache<String, String> userListSource = CacheBuilder.newBuilder()
   .maximumSize(1)
   .expireAfterWrite(10, TimeUnit.MINUTES)
   // ... other configuration builder methods ...
   .build(
       new CacheLoader<String, String>() {
         public Graph load(Key key) {
           return callToYourThirdPartyLibrary();
         }
       });

You can hide the fact that the ignored key exists at all, by wrapping it in another method:

  public String userList() {
        return userListSource.get("key is irrelevant");
  }

It doesn't feel as if you need all the power of a Guava cache in your use case. It expires the cache after a time period, and supports removal listeners. Do you really need this? You could write something very simple instead like:

 public class UserListSource {
     private String userList = null;
     private long lastFetched;
     private static long MAX_AGE = 1000 * 60 * 5; // 5 mins

     public String get() {
        if(userList == null || currentTimeMillis() > lastFetched + MAX_AGE) {
             userList = fetchUserListUsingThirdPartyApi();
             fetched = currentTimeMillis();
        }
        return userList;
     }
 }
slim
  • 40,215
  • 13
  • 94
  • 127
  • 3
    For the last example, you could also use something like `Suppliers#memoizeWithExpiration` https://google.github.io/guava/releases/19.0/api/docs/com/google/common/base/Suppliers.html#memoizeWithExpiration(com.google.common.base.Supplier, long, java.util.concurrent.TimeUnit) – forrert Dec 16 '16 at 17:25