okaywit / guava-libraries

Automatically exported from code.google.com/p/guava-libraries
Apache License 2.0
0 stars 0 forks source link

Add a reloadAll method to the CacheLoader #1466

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Hi,
We have a usecase which seems, at least from the documentation I've read, to be 
more corner case but I think is valid and relevant.
We have several places where we need to load an entire dictionary (Map<K,V<) on 
startup and then reload that entire dictionary every 5 minutes.
The dictionary source is remote (RPC/Rest/DB) and the dictionary changes 
together at all times.
An example for this can be the running A/B tests or running feature toggles; 
These change relatively infrequently and it is ok to get a stale copy for a few 
minutes (hence the 5 minutes refresh).
I'd like to be able to do something like this:

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
       .refreshAllAfterWrite(5, TimeUnit.MINUTES)
       .build(
           new CacheLoader<Key, Graph>() {
             public Graph load(Key key) { // no checked exception
               throw new UnsupportedOperationException ("single key loading is unsupported");
             }
             public ListenableFuture<Graph> reload(final Key key, Graph prevGraph) {
                throw new UnsupportedOperationException ("single key loading is unsupported");
             } 
            public Map<K,V> loadAll(Iterable<? extends K> keys){ // i ignore the keys
                return getAllGraphsFromDatabase();
             }
             public ListenableFuture<Map<Key,Graph>> reloadAll() { //i really don't need any keys here
                 // asynchronous!
                 ListenableFutureTask<Map<Key,Graph>> task = ListenableFutureTask.create(new   Callable<Map<Key,Graph>>() {
                   public Graph call() {
                     return getAllGraphsFromDatabase();
                   }
                 });
                 executor.execute(task);
                 return task;
             }
           });

Additionally I'd like to be able to specify "refreshAllAfterWrite" which will 
trigger the call reloadAll.

Would be happy to specify more about our usecase if needed.

Original issue reported on code.google.com by itt...@wix.com on 3 Jul 2013 at 6:20

GoogleCodeExporter commented 9 years ago
It sounds to me like you could just create a Supplier<Map<K, V>> that loads 
your whole map, then wrap it with Suppliers.memoizeWithExpiration(supplier, 5, 
MINUTES). Then just have a method for getting the Map that calls 
memoizingSupplier.get().

Original comment by cgdecker@google.com on 3 Jul 2013 at 3:03

GoogleCodeExporter commented 9 years ago
So my code should call a method that does something like:
public V get(K key){ return supplier.get().get(key);}
instead of interacting with the cache?
that's possible, i don't know if this is really clean but possible.

Actually after reading a bit it seems that memoizeWithExpiration doesn't work 
async so is not relevant for us (i'm referring to this issue 
https://code.google.com/p/guava-libraries/issues/detail?id=872). Am I wrong?

Original comment by itt...@wix.com on 3 Jul 2013 at 4:40

GoogleCodeExporter commented 9 years ago
Ah, yes, memoizeWithExpiration wouldn't reload asynchronously. This does feel a 
lot like a single-element cache, since you're really just dealing with loading 
a single Map rather than doing any of the key-level caching LoadingCache is 
designed for.

Original comment by cgdecker@google.com on 3 Jul 2013 at 5:36

GoogleCodeExporter commented 9 years ago
Yeah. Except for the need to hide the supplier.get call I really prefer the 
single element cache because that is what I need.
​Do you happen to know what's the status of that issue?

On Wed, Jul 3, 2013 at 8:36 PM, null <guava-libraries@googlecode.com>
wrote:

Original comment by itt...@wix.com on 3 Jul 2013 at 7:10

GoogleCodeExporter commented 9 years ago
I'm gonna mark this as a duplicate of that issue. Maybe Louis knows more about 
the status of that issue, though I think there isn't much to report... it's in 
the Research bucket which means it needs more investigation when we have time 
(and more information and use cases from people who want it).

In the meantime you could just create a LoadingCache using a single dummy key 
and use the refreshAfterWrite() policy to handle refreshing for you.

Original comment by cgdecker@google.com on 3 Jul 2013 at 7:24

GoogleCodeExporter commented 9 years ago
(Or, I should say, I think you could do that. I'm not an expert on caching 
stuff.)

Original comment by cgdecker@google.com on 3 Jul 2013 at 7:30

GoogleCodeExporter commented 9 years ago
We actually have our own homebrew single element cache we wrote so I'll avoid 
the hacks while I can but thanks.

On Wed, Jul 3, 2013 at 10:30 PM, null <guava-libraries@googlecode.com>
wrote:

Original comment by itt...@wix.com on 4 Jul 2013 at 3:46

GoogleCodeExporter commented 9 years ago
I need this too....is this already done?

Original comment by iwalkalo...@gmail.com on 23 Apr 2014 at 11:38

GoogleCodeExporter commented 9 years ago
This issue has been migrated to GitHub.

It can be found at https://github.com/google/guava/issues/<issue id>

Original comment by cgdecker@google.com on 1 Nov 2014 at 4:12

GoogleCodeExporter commented 9 years ago

Original comment by cgdecker@google.com on 3 Nov 2014 at 9:08