2012-09-17 12 views
6

का जवाब देते समय अक्का ने रैपिंग भविष्य से परहेज किया, मैं अक्का 2 के साथ एक छोटा कैशिंग अभिनेता बना रहा हूं और अभिनेता को ब्लॉक नहीं करने के लिए मैं वायदा के अंदर सभी गणना करता हूं। हालांकि एक समस्या यह है कि इस अभिनेता को ऐसे कोड के साथ बातचीत करने की भी आवश्यकता है जो खुद अभिनेता में नहीं है, ताकि मुझे मूल्य प्राप्त करने के लिए "पूछने" पैटर्न का उपयोग करने की आवश्यकता हो।गैर-अभिनेता कोड

मेरा सवाल है, मैं पूछताछ पैटर्न का उपयोग करते समय किसी अन्य भविष्य के अंदर अपनी गणना के भविष्य को लपेटने से कैसे बचूं?

उदाहरण के लिए

val f = myCache ? GetOrCalc("myKey", myCalculation) // this will be a Future[Future[...]] but I would like a Future[...] 

// meanwhile, inside the actor 
def receive = { 
    case GetOrCalc(key, calculation) => 
     if (keyNotExists) sender ! Future { calculation() } // calculation() is long-running 
     else sender ! cacheMap(key) 
} 

आदर्श रूप में मैं Future.pipeTo समारोह इस्तेमाल कर सकते हैं लेकिन मुझे डर है इस गैर अभिनेता कोड के लिए एक "प्रतिक्रिया" के रूप में गिना नहीं प्राप्त करता हूँ

उत्तर

6

यह समाधान है:

val f = myCache ? GetOrCalc("myKey", myCalculation) 

def receive = { 
    case GetOrCalc(key, calculation) => 
     if (keyNotExists) Future { calculation() } pipeTo sender 
     else sender ! cacheMap(key) 
} 

संदेश-और-प्राप्त-फ्यूचर "> http://doc.akka.io/docs/akka/2.0.3/scala/actors.html# Ask_Send-and-Receive-future

+0

आश्चर्यजनक रूप से, यह वही है जो मेरे मूल छद्म कोड में था और मैंने इसका परीक्षण भी नहीं किया क्योंकि मुझे लगता है कि पाइप "प्रतिक्रिया" के रूप में काम नहीं करेगा। परीक्षण और परीक्षण करने के लिए मुझे यही मिलता है! यद्यपि सच्चाई बताई जा सकती है कि जैसा कि मैंने उपर्युक्त उल्लेख किया है, यह व्यवहार दस्तावेज़ों में नहीं है। बहुत बहुत विक्टर धन्यवाद! – Aktau

+3

क्लैंग पर भरोसा करें –

+0

मैं सोच रहा हूं कि "पाइप टू प्रेषक" सुरक्षित रूप से प्रेषक तक कैसे पहुंच रहा है। मैं समझता हूं कि आप भविष्य में प्रेषक से क्यों नहीं पहुंच सकते हैं, लेकिन पाइप कैसे आते हैं प्रेषक के पास एक ही समस्या नहीं है। क्या ऐसा इसलिए है क्योंकि पाइप भविष्य के पूरा होने से पहले अभिनेता के संदर्भ में प्रेषक का मूल्यांकन करता है? –

3

को onComplete जोड़े गणना भविष्य।

def receive = { 
    case GetOrCalc(key, calculation) => 
     if (keyNotExists) // calculation() is long-running 
      Future { calculation() } onComplete { 
       case Right(result) => result match { 
         case Some(value) => sender ! value 
         case None => sender ! Status.Failure(new Exception("Cannot find the value")) 
        } 
       case Left(ex) => 
        sender ! Status.Failure(ex) 

      } 
     else sender ! cacheMap(key) 
} 

और कैश सिस्टम बनाने के लिए अक्का का उपयोग करने के बारे में एक लेख है। http://letitcrash.com/post/30509298968/case-study-an-auto-updating-cache-using-actors

+0

लेकिन क्या यह दो बार नहीं भेजता है? एक बार भविष्य [भविष्य [...]] (प्रेषक! भविष्य {...}) और एक और समय भविष्य [...] (प्रेषक! मूल्य)? क्या यह गैर-अभिनेता कॉलिंग कोड के लिए काम करता है? आप CalcResult संदेश का उपयोग कैसे करते हैं? – Aktau

+2

कोड अपडेट किया गया। असल में यह समाधान आलेख से आ रहा है (http://letitcrash.com/post/30509298968/case -स्टूडी-ए-ऑटो-अपडेटिंग-कैश-यूट-एक्टर्स) और मेरे पास समय नहीं है अब के लिए इसे rify। आशा है कि यह आपके लिए एक उपयोगी सुराग है। –

+0

हे, धन्यवाद! मैं कुछ घंटे पहले उस स्रोत को पढ़ रहा था क्योंकि वास्तव में यह अक्का और कैशिंग के बारे में बात करता है। मुझे लगता है कि मैंने इसे पूरी तरह से पर्याप्त नहीं पढ़ा था, ऐसा लगता है कि मैं करीब निरीक्षण के बाद उन चीजों को कम या ज्यादा करना चाहता था। यदि यह अपेक्षित काम करता है तो मैं आपके उत्तर को सही – Aktau