2013-08-02 13 views
26

मैं जावा पुस्तकालय के चारों ओर एक छोटा सा स्काला रैपर लिखने की प्रक्रिया में हूं।सुस्त भविष्य के लिए भविष्य

  • अमल (क्वेरी): परिणाम
  • asyncExecute (क्वेरी): ListenableFuture [परिणाम]

इस संदर्भ में ListenableFuture है

जावा पुस्तकालय एक वस्तु QueryExecutor 2 तरीकों को उजागर किया गया है अमरूद पुस्तकालय से एक।

मैं चाहता हूं कि मेरा स्कैला रैपर जावा ऑब्जेक्ट के बजाय भविष्य [परिणाम] लौटाए, लेकिन मुझे यकीन नहीं है कि इसे लागू करने का सबसे अच्छा तरीका क्या है।

future { 
    executor.execute(query) 
} 

और

val p = promise[Result] 
val guavaFuture = executor.asyncExecute(query) 

Futures.addCallback(guavaFuture, new FutureCallback[Result] { 
    def onFailure(t: Throwable) { 
    p.failure(t) 
    } 

    def onSuccess(result: Result) { 
    p.success(result) 
    } 
}) 

p.future 

मैं सोच रहा हूँ कि कौन सी विधि सबसे अच्छा है: यहाँ 2 समाधान मैं के साथ आया है। मेरा अंतर्ज्ञान यह है कि पहला, एक भविष्य लौटने पर, अभी भी एक थ्रेड को अवरुद्ध कर देगा, जबकि कॉल करने के लिए कॉल प्रतिक्रिया के लिए इंतजार कर रहा है, दूसरा ऐसा लगता है कि यह वास्तव में गैर अवरोध होना चाहिए। प्रत्येक विधि के पेशेवरों/विपक्ष पर कोई टिप्पणी?

+2

चलें मान लें कि आपके 4 प्रोसेसर है। इस मामले में डिफ़ॉल्ट 'ExecutionContext' में 4 कर्मचारी होते हैं। प्रत्येक 'भविष्य {execor.execute (क्वेरी)}' ब्लॉक 1 कार्यकर्ता, इसलिए 4 "वायदा" आपके प्रोग्राम को पूरी तरह अवरुद्ध कर देगा। आप संचालन को अवरुद्ध करने के लिए अतिरिक्त 'निष्पादन कॉन्टेक्स्ट' बना सकते हैं, लेकिन कुछ ओवरहेड होगा। – senia

+0

धन्यवाद @senia, यही मैंने सोचा था। पहला कोड कॉलर के दृष्टिकोण से एसिंक है लेकिन अभी भी ExecutionContext के थ्रेड को अवरुद्ध कर देगा, जबकि दूसरा वास्तव में अवरुद्ध नहीं है (मान लेता है कि asyncExecute गैर अवरोधक IO का उपयोग करता है)। मुझे लगता है कि यह एक बहुत ही बुनियादी सवाल है लेकिन मैं वादे से बहुत परिचित नहीं हूं। – vptheron

+1

मुझे यह एक समान (या संभव भी समान) आवश्यकता में सहायक होने के लिए मिला: https://github.com/eigengo/activator-akka-cassandra/blob/master/src/main/scala/core/cassandra.scala – Gavin

उत्तर

37

दूसरा विकल्प सबसे अच्छा है, यह सब कुछ अतुल्यकालिक रखता है। लेकिन ... आप एक पुन: प्रयोज्य पैटर्न में एक बेहतर और अमूर्त समाधान कर सकते हैं:

implicit class RichListenableFuture[T](lf: ListenableFuture[T]) { 
    def asScala: Future[T] = { 
    val p = Promise[T]() 
    Futures.addCallback(lf, new FutureCallback[T] { 
     def onFailure(t: Throwable): Unit = p failure t 
     def onSuccess(result: T): Unit = p success result 
    }) 
    p.future 
    }  
} 

आप तो बस फोन कर सकते हैं:

executor.asyncExecute(query).asScala 
+1

बहुत बढ़िया समाधान। विश्वास नहीं कर सकता कि मेरे सुने जाने योग्य भविष्य इंटरफ़ेसिंग कोड कितना क्लीनर है इस अंतर्निहित –

+2

बहुत अच्छा है। 'वादा [टी] ' – raam86

+0

का उपयोग करके और भी अमूर्त हो सकता है, लेकिन मदद नहीं कर सकता है कि समझौता वास्तव में भविष्य लौटाता है। ;) अन्यथा, इसे प्यार करो! –

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