2010-07-28 9 views
5

के साथ एकाधिक वायदा का उपयोग करते समय लटकता है, मैं एक मेजबान पर दो रिमोट एक्टर्स शुरू करता हूं जो उन्हें जो कुछ भी भेजा जाता है उसे गूंजता है। मैं फिर एक और अभिनेता बनाता हूं जो दोनों कलाकारों को कुछ संदेश भेजता है (!! !! !!) और इन कलाकारों के उत्तरों को रखने वाले भविष्य की वस्तुओं की एक सूची रखता है। फिर मैं प्रत्येक भविष्य के परिणाम लाने के लिए इस सूची पर लूप करता हूं। समस्या यह है कि ज्यादातर समय कुछ वायदा कभी वापस नहीं आते हैं, यहां तक ​​कि अभिनेता का दावा है कि उसने जवाब भेजा है। समस्या यादृच्छिक रूप से होती है, कभी-कभी यह पूरी सूची के माध्यम से मिल जाएगी, लेकिन ज्यादातर समय यह किसी बिंदु पर फंस जाता है और अनिश्चित काल तक लटकता है।प्रोग्राम कई रिमोट एक्टर्स

Sink.scala:

import scala.actors.Actor 
import scala.actors.Actor._ 
import scala.actors.Exit 
import scala.actors.remote.RemoteActor 
import scala.actors.remote.RemoteActor._ 

object Sink { 
    def main(args: Array[String]): Unit = { 
    new RemoteSink("node03-0",43001).start() 
    new RemoteSink("node03-1",43001).start() 
    } 
} 
class RemoteSink(name: String, port: Int) extends Actor 
{ 
def act() { 
    println(name+" starts") 
    trapExit=true 
    alive(port) 
    register(Symbol(name),self) 

    loop { 
     react { 
      case Exit(from,reason) =>{ 
        exit() 
      } 
      case msg => reply{ 
        println(name+" sending reply to: "+msg) 
        msg+" back at you from "+name 
       } 
     } 
    } 
} 
} 

Source.scala:

import scala.actors.Actor 
import scala.actors.Actor._ 
import scala.actors.remote.Node; 
import scala.actors.remote.RemoteActor 
import scala.actors.remote.RemoteActor._ 

object Source { 
    def main(args: Array[String]):Unit = { 
     val peer = Node("127.0.0.1", 43001) 
     val source = new RemoteSource(peer) 
     source.start() 
    } 
} 
class RemoteSource(peer: Node) extends Actor 
{ 
    def act() { 
     trapExit=true 
     alive(43001) 
     register(Symbol("source"),self) 

     val sinks = List(select(peer,Symbol("node03-0")) 
            ,select(peer,Symbol("node03-1")) 
           ) 
     sinks.foreach(link) 

     val futures = for(sink <- sinks; i <- 0 to 20) yield sink !! "hello "+i 
     futures.foreach(f => println(f())) 

     exit() 
    } 
} 

मैं गलत क्या कर रहा हूँ

यहाँ कुछ कोड है जो मेरे मशीन पर समस्या पैदा करता है? इसके परिणाम के लिए इंतजार,

जिसमें
futures.foreach(f => println(f())) 

आप बदले में प्रत्येक पर अपने सभी वायदा के माध्यम से लूप और ब्लॉक:

+0

मैंने प्रत्येक अभिनेता के लिए एक अलग बंदरगाह का उपयोग करने का भी प्रयास किया है, लेकिन एक ही परिणाम प्राप्त करें। – Kevin

उत्तर

2

मैं आपकी समस्या को अनुमान है कि इस लाइन के कारण है। वायदा पर अवरुद्ध करना आम तौर पर एक बुरा विचार है और इससे बचा जाना चाहिए। इसके बजाय आप क्या करना चाहते हैं करने के लिए एक क्रिया निर्दिष्ट करें जब भविष्य का परिणाम उपलब्ध हो। इस प्रयास करें:

futures.foreach(f => f.foreach(r => println(r))) 

यहाँ एक वैकल्पिक तरीका समझ के लिए एक साथ कि कहने के लिए है:

for (future <- futures; result <- future) { println(result) } 

This blog entry वायदा पर अवरुद्ध की समस्या और कैसे monadic वायदा इसे दूर पर एक उत्कृष्ट प्राइमर है।

+0

आपके उत्तर के लिए धन्यवाद, मुझे लगता है कि अब मैं समस्या को बेहतर समझता हूं। हालांकि, आपके द्वारा प्रदान किए गए कोड का यह बिट भी अजीब तरीके से कार्य करता है। यह पहले भविष्य को संसाधित करता है और फिर अपवाद फेंकने के बिना कार्यक्रम को समाप्त करता है। मैंने Futures.awaitAll (10000, वायदा) का उपयोग करने का भी प्रयास किया, लेकिन 10 सेकंड के बाद भी अभी भी अनुपलब्ध परिणाम हैं। – Kevin

+0

यह समाप्त हो जाता है क्योंकि आप लूप के बाद बाहर निकलें() को कॉल करते हैं। लूप तुरंत मेरे कोड के साथ वापस आ जाएगा क्योंकि यह अब अवरुद्ध नहीं है, इसलिए आप बस वहां से बाहर निकलना नहीं चाहते हैं। –

+0

नहीं, यह इससे पहले समाप्त हो गया है, मैंने प्रिंट स्टेटमेंट्स और लूप और अन्य डिबगिंग सामग्री को जोड़ा है। मैं समझता हूं कि यह पाश अवरुद्ध नहीं होगा, लेकिन उस पंक्ति के बाद कुछ भी संसाधित नहीं हो जाता है। कोई विचार क्यों Futures.awaitAll काम नहीं करता है? ऐसा लगता है कि यह विशेष रूप से इस तरह के कार्य के लिए लिखा गया था। – Kevin

0

मैंने भी इसी तरह के मामले को देखा है। जब थ्रेड के अंदर कोड कुछ प्रकार के अपवाद और बाहर निकलता है, तो इसी भविष्य में। कभी वापस नहीं आती। कोई java.lang.Error बनाम java.lang का अपवाद उठाने का प्रयास कर सकता है। NoSuchMethodError। उत्तरार्द्ध का भविष्य भविष्य कभी वापस नहीं आएगा।

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