Skip to content

Instantly share code, notes, and snippets.

@kdrakon
Created April 10, 2014 15:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save kdrakon/10396036 to your computer and use it in GitHub Desktop.
Save kdrakon/10396036 to your computer and use it in GitHub Desktop.
A Guava cache that defaults to old values in the event of failure
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListenableFutureTask;
public class KindaLikeASelfRefreshingCache
{
static class CacheLoaderA extends CacheLoader<String, String>
{
private static final ExecutorService service = Executors.newSingleThreadScheduledExecutor();
private volatile boolean shouldFail = true;
@Override
public String load(String key) throws Exception
{
/*
* The first call to load() happens on the first get() of the cache. Subsequent calls
* are made concurrently via the reload() method.
*/
// we'll fail every other execution
shouldFail = !shouldFail;
if (shouldFail)
{
System.out.println("Throwing exception, we'll be returning the old value for now");
throw new Exception();
}
return key.concat("_VALUE");
}
@Override
public ListenableFuture<String> reload(final String key, final String oldValue) throws Exception
{
System.out.println("Starting concurrent thread to get new value");
ListenableFutureTask<String> task = ListenableFutureTask.create(new Callable<String>() {
@Override
public String call() throws Exception
{
try
{
// try to get a new value
return load(key);
} catch (Throwable e)
{
// or return the old one in the event of failure
return oldValue;
}
}
});
// run in the background so that concurrent get() requests still return values.
service.execute(task);
return task;
}
}
public static void main(String[] args) throws InterruptedException
{
LoadingCache<String, String> cache =
CacheBuilder.newBuilder().refreshAfterWrite(2, TimeUnit.SECONDS).build(new CacheLoaderA());
while (true)
{
/*
* I make requests faster than the timeout above to show that values -- 'old' or 'new'
* are consistently returned
*/
Thread.sleep(500);
try
{
System.out.println("Returning: " + cache.get("key"));
} catch (ExecutionException e)
{
// should never happen
}
}
}
}
@baikaishuili
Copy link

this is what i want ,thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment