2012-07-17 10 views
13

एक प्ले फ्रेमवर्क 2.0.1 (स्काला) आवेदन में, हम जो java.util.concurrent.Future रिटर्न प्रतिक्रियाओं के रूप में एक वेब सेवा क्लाइंट लाइब्रेरी का उपयोग कर रहे हैं।मैं एक java.util.concurrent कैसे लपेट सकता हूं। भविष्य में एक अक्का भविष्य में?

इसके बजाय get() फोन पर खेलो एप्लिकेशन को बाधित करने के लिए, हम एक akka.dispatch.Future में j.u.c.Future रैप करने के लिए, ताकि हम आसानी से खेलने ढांचे के AsyncResult प्रसंस्करण का उपयोग कर सकते करना चाहते हैं।

किसी को भी यह किया पहले, या एक पुस्तकालय या उदाहरण कोड है गया है?


अद्यतन: निकटतम बात हमने पाया है इस Google समूह चर्चा है: https://groups.google.com/forum/#!topic/play-framework/c4DOOtGF50c

... अगर आपके पास एक सादे jucFuture सबसे अच्छा आप बनाना क्या कर सकते हैं एक गैर अवरुद्ध समाधान jucFuture और एक वादा लेते हैं, और उन्हें एक मतदान पाश जब यह किया जाता है कि भविष्य के परिणाम के साथ वादा पूरा हो जाएगा चल कुछ धागा करने के लिए दे रहा है।

किसी को भी इस का एक उदाहरण दिया गया है?

उत्तर

7

@ विकटर क्लैंग: हम समझते हैं कि j.u.c.Future एक घृणा है। लेकिन यही वह है जो हम सॉफ्टवेयर के एक टुकड़े से वापस आ रहे हैं जिसे हमें समय के लिए स्वीकार किया जाना चाहिए।

अब तक, यह है कि क्या हम साथ काट दिया गया है:

def wrapJavaFutureInAkkaFuture[T](javaFuture: java.util.concurrent.Future[T], maybeTimeout: Option[Duration] = None)(implicit system: ActorSystem): akka.dispatch.Future[T] = { 
    val promise = new akka.dispatch.DefaultPromise[T] 
    pollJavaFutureUntilDoneOrCancelled(javaFuture, promise, maybeTimeout.map(_.fromNow)) 
    promise 
} 

दूसरे शब्दों में, एक अलग अक्का Promise (एक Future के लिखने की ओर) j.u.c.Future करने के लिए इसी बनाते हैं, तो कॉलबैक की शुरूआत की pollJavaFutureUntilDoneOrCancelled मतदान से वादा "abomination" अपडेट करते हैं और फोन करने वाले के लिए वादा देता है।

तो हम j.u.c. भविष्य की स्थिति के आधार पर अक्का वादा को अद्यतन करने के लिए "मतदान" कैसे करते हैं?

def pollJavaFutureUntilDoneOrCancelled[T](javaFuture: java.util.concurrent.Future[T], promise: akka.dispatch.Promise[T], maybeDeadline: Option[Deadline] = None)(implicit system: ActorSystem) { 
    if (maybeDeadline.exists(_.isOverdue)) javaFuture.cancel(true); 

    if (javaFuture.isDone || javaFuture.isCancelled) { 
    promise.complete(allCatch either { javaFuture.get }) 
    } else { 
    Play.maybeApplication.foreach { implicit app => 
     system.scheduler.scheduleOnce(50 milliseconds) { 
     pollJavaFutureUntilDoneOrCancelled(javaFuture, promise, maybeDeadline) 
     } 
    } 
    } 
} 

यह एक ऐसा प्रयास है जिसे Google समूह चर्चा में संकेत दिया गया था जिसे मैंने प्रश्न में संदर्भित किया था। यह Akka शेड्यूलर का उपयोग यह जांचने के लिए कि प्रत्येक j.u.c.Future या तो किया जाता है या रद्द किया जाता है, उसे हर 50 एमएस वापस कॉल करने के लिए उपयोग करता है। जब भी ऐसा होता है, यह पूरे राज्य के साथ अक्का वादा को अद्यतन करता है।

@Victor Klang, एट अल:

इस सर्वोत्तम प्रक्रिया है? क्या आप ऐसा करने के बेहतर तरीके से जानते हैं? क्या हम यहां एक नकारात्मक पक्ष खो रहे हैं जिसके बारे में हमें पता होना चाहिए?

किसी भी और मदद के लिए धन्यवाद।

+0

एक स्पष्ट नकारात्मक पक्ष यह है, कि सबसे खराब स्थिति में इस प्रतिक्रिया के एक उच्च देरी का कारण होगा। यदि आपके पास उदाहरण के लिए डिफ़ॉल्ट सेटिंग्स हैं और आपका भविष्य चेक के बाद 1 एमएस पूरा करता है, तो इससे लगभग 100ms की देरी हो सकती है। हालांकि इसे 'शेड्यूलर' सेट करके समायोजित किया जा सकता है।कॉन्फ़िगरेशन में टिक-अवधि 'सेटिंग। – drexin

+0

@ ड्रेक्सिन सच है, लेकिन एक टिक अवधि और मतदान आवृत्ति व्यापार-बंद किसी भी मतदान आधारित समाधान में मौजूद होगा, है ना? –

+1

निश्चित रूप से, लेकिन जैसा कि आपने डाउनसाइड्स के लिए कहा था, मैं बस आपको बताना चाहता था कि यह न केवल 'शेड्यूलऑन' कॉल के देरी परम पर निर्भर करता है, बल्कि अक्का कॉन्फ़िगरेशन में सेटिंग पर भी निर्भर करता है। यदि आप देरी से जी सकते हैं तो यह एक उपयोगी समाधान होना चाहिए। – drexin

0

आप java.util.concurrent.Callable साथ akka.dispatch.Futures.future() उपयोग करना चाहिए:

val akkaFuture: akka.dispatch.Future[String] = akka.dispatch.Futures.future(
    new java.util.concurrent.Callable[String] { 
    def call: String = { 
     return "scala->" + javaFuture.get 
    } 
}, executionContext) 

Gist for complete example

+0

यह आवश्यक रूप से आवश्यकतानुसार अधिक धागे में परिणाम देता है, इनमें से एक ब्लॉक, और मुख्य धागे पर javaFuture.get को कॉल करने से बेहतर नहीं है। अक्का भविष्य का परिचय यहां चरम स्थितियों को छोड़कर फायदेमंद नहीं है जहां घटक संगतता की बिल्कुल आवश्यकता है। – vishr