2012-04-14 7 views
7

दो चीजें जो मुझे वास्तव में गुवा 11 के कैशलोडर (धन्यवाद, Google!) के बारे में पसंद है, सभी लोड हैं(), जो मुझे एक साथ कई कुंजी लोड करने की अनुमति देता है, और पुनः लोड(), जो मुझे "अबाध" होने पर एक कुंजी को असीमित रूप से फिर से लोड करने की अनुमति देता है लेकिन पुराना मान मौजूद है। मैं उत्सुक हूं कि वे एक साथ कैसे खेलते हैं, क्योंकि पुनः लोड() एक एकल कुंजी पर चल रहा है।Google गुवा का कैशलोडर लोडअल() बनाम रीलोड() सेमेन्टिक्स

Concretely, CachesExplained से उदाहरण का विस्तार:

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder() 
    .maximumSize(1000) 
    .refreshAfterWrite(1, TimeUnit.MINUTES) 
    .build(
     new CacheLoader<Key, Graph>() { 
     public Graph load(Key key) { // no checked exception 
      return getGraphFromDatabase(key); 
     } 

     public Map<Key, Graph> loadAll(Iterable<? extends K> keys) { 
      return getAllGraphsFromDatabase(keys); 
     } 

     public ListenableFuture<Graph> reload(final Key key, Graph prevGraph) { 
      if (neverNeedsRefresh(key)) { 
      return Futures.immediateFuture(prevGraph); 
      } else { 
      // asynchronous! 
      return ListenableFutureTask.create(new Callable<Graph>() { 
       public Graph call() { 
       return getGraphFromDatabase(key); 
       } 
      }); 
      } 
     } 
     }); 

... जहां "getAllGraphsFromDatabase()" एक समग्र डेटाबेस क्वेरी बल्कि लंबाई से करता है (कुंजी) अलग-अलग प्रश्नों।

लोडिंग कैशे के इन दो घटक एक साथ कैसे खेलते हैं? अगर मेरे अनुरोध में कुछ कुंजी कैश में मौजूद नहीं हैं() कैश में मौजूद नहीं हैं, तो उन्हें loadAll() वाले समूह के रूप में लोड किया जाता है, लेकिन अगर कुछ को ताज़ा करने की आवश्यकता है, तो क्या वे लोड() के साथ अलग-अलग पुनः लोड हो जाते हैं? यदि हां, तो क्या एक reloadAll() का समर्थन करने की योजना है?

+0

[Cache.getAll ताज़ा करने में विफल रहता है # 971] (https://github.com/google/guava/issues/971) अभी भी – Vadzim

उत्तर

13

यहां कितना ताज़ा काम करता है। cache.refresh(key) साथ

  1. स्पष्ट रूप से,:

    एक कैश प्रविष्टि पर रिफ्रेशिंग दो तरह से शुरू किया जा सकता।

  2. स्पष्ट रूप से, यदि कैश refreshAfterWrite के साथ कॉन्फ़िगर किया गया है और प्रविष्टि क्वेरी लिखने के बाद निर्दिष्ट समय के बाद है।

यदि एक प्रविष्टि जो रीलोड के लिए योग्य है पूछताछ की जाती है, तो पुराना मान वापस कर दिया जाता है, और एक (संभवतः असीमित) रीफ्रेश ट्रिगर होता है। रीफ्रेश प्रगति पर है, जबकि कैश कुंजी के लिए पुराना मान वापस जारी रखेगा। (तो अगर एक getAll अनुरोध में कुछ सुझाव दिए ताज़ा के लिए पात्र हैं, उनके पुराने मूल्यों लौटे जाएगा, लेकिन उन कुंजियों के लिए मान होंगे (संभवतः एसिंक्रोनस रूप से) पुनः लोड।)

CacheLoader.reload(key, oldValue) की डिफ़ॉल्ट कार्यान्वयन सिर्फ Futures.immediateFuture(load(key)) रिटर्न , जो (सिंक्रनाइज़) मूल्य को दोबारा लागू करता है। यदि आप कैश रीफ्रेश करने की अपेक्षा करते हैं तो अधिक परिष्कृत, एसिंक्रोनस कार्यान्वयन की अनुशंसा की जाती है।

मुझे नहीं लगता कि हम इस समय reloadAll प्रदान करने के इच्छुक हैं। मुझे संदेह है कि यह संभव है, लेकिन चीजें जितनी जटिल हैं उतनी जटिल हैं, और मुझे लगता है कि हम तब तक प्रतीक्षा करने के इच्छुक हैं जब तक हम ऐसी चीज की विशिष्ट मांग नहीं देखते।

+0

वोट करने के लिए खुला है, मुझे पता था कि आप सभी ओवरफ़्लो पर हैं, यही कारण है कि मैंने सोचा कि मैं यहाँ पूछूंगा। धन्यवाद! इसलिए, अगर मैं एक getAll() कॉल करता हूं, तो मेरे पास संभावित रूप से तीन प्रकार की चाबियाँ हो सकती हैं। वे जो कैश में मौजूद हैं (और ताजा), जो कैश में नहीं हैं, और जो मौजूद हैं (और ताज़ा करने के लिए तैयार हैं)। जो मौजूद हैं वे कैश से लौटाए गए हैं, जो मौजूद नहीं हैं, वे मेरे लोडएल() फ़ंक्शन के माध्यम से खींचे जाते हैं, और जो कैश में मौजूद हैं लेकिन रीफ्रेश के लिए तैयार हैं, पुराने मान लौटे हैं लेकिन फिर एक-एक करके पुनः लोड किए जाते हैं असीमित रूप से? क्या वो सही है? – spitzanator

+0

ठीक है, "एक करके एक" और "असीमित" मैं शब्दावली का उपयोग नहीं करता हूं, लेकिन मुझे पूरा यकीन है कि आपको यह सही मिला है। (हालांकि तत्वों को व्यक्तिगत रूप से रीफ्रेश किया जाएगा, फिर भी उनके रीफ्रेश _concurrent_ होंगे।) –

+0

धन्यवाद! क्या यह नियंत्रित करने का कोई तरीका है कि कितने समवर्ती रीफ्रेश होते हैं इसलिए मैं अपना डेटाबेस नहीं करता हूं?अगर मैं 100 कैश के लिए अपने कैश से पूछता हूं, तो मैं स्टेल वैल्यू रीफ्रेश करने के लिए 9 0 समांतर व्यक्तिगत डेटाबेस अनुरोधों से बचना चाहता हूं, जब एक ही क्वेरी उन्हें लाने के लिए पर्याप्त होती है। – spitzanator

संबंधित मुद्दे