2010-07-28 15 views
5

Bir ana makineye iki tane uzaktan aktör başlıyorum. Daha sonra, her iki oyuncuya da birtakım mesajlar (! Kullanarak) gönderen ve bu aktörlerden gelen cevapları tutan Gelecek Nesnelerinin bir listesini tutan başka bir aktör yaratıyorum. Ardından, her Geleceğin sonucunu almak için bu listeye geçiyorum. Sorun şu ki, çoğu zaman, bazı gelecekler asla geri dönmez, hatta oyuncu, cevabı gönderdiğine inanıyordu. Sorun rastgele oluyor, bazen tüm listeden geçiyor, ancak çoğu zaman bir noktada sıkışıp kalıyor ve süresiz duruyor.programı birden çok uzaktaki aktörler ile birden çok geleceği kullanırken askıda kalıyor

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() 
    } 
} 

Neyi yanlış yapıyorum İşte

benim makinede problem üreten bazı kodudur? Sorununu tahmin ediyorum

+0

Ayrıca her oyuncu için farklı bir bağlantı noktası kullanmayı denedim, ancak aynı sonucu elde ettim. – Kevin

cevap

2

nedeniyle bu hat şudur: sırayla her on

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

yılında tüm gelecekleri döngü ve blok onun sonucu bekliyor. Gelecekleri bloke etmek genellikle kötü bir fikirdir ve bundan kaçınılmalıdır. Bunun yerine, gelecekteki sonuç kullanılabilir olduğunda gerçekleştirmek için bir eylem belirtin. Bu deneyin:

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

İşte anlama için bir ile söylemek alternatif bir yolu:

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

This blog entry vadeli engelleme sorunu ve nasıl monadic vadeli üstesinden mükemmel bir astardır.

+0

Cevabınız için teşekkürler, sorunu daha iyi anladığımı düşünüyorum. Ancak, sağladığınız bu kod biraz garip davranır. İlk geleceği işler ve ardından bir istisna atmadan programı sonlandırır. Ayrıca Futures.awaitAll (10000, futures) kullanmayı denedim, ancak 10 saniye sonra hala eksik sonuçlar var. – Kevin

+0

Döngüden sonra exit() yöntemini çağırdığınız için sonlanır. Döngü hemen kodumla geri dönecek çünkü artık engellenmiyor, o yüzden artık oradan çıkmak istemiyorsunuz. –

+0

no, bundan önce sona eriyor, ben baskı ifadeleri ve döngüler ve birçok diğer hata ayıklama şeyler ekledim. Bu döngünün engellenmeyeceğini anlıyorum, ama bu çizgiden sonra hiçbir şey işlenmez. Futures.awaitAll neden çalışmıyor? Bu tür bir görev için özel olarak yazılmış gibi görünüyor. – Kevin

0

Benzer bir durumu da gördüm. İş parçacığı içindeki kod, belirli özel durum ve çıkış türlerini atarken, ilgili future.get hiçbir zaman geri dönmez. Bir java.lang.Error ve java.lang.NoSuchMethodError istisnasının yükseltilmesi ile deneyebilirsiniz. İkincisinin geleceği asla geri dönmeyecek.

İlgili konular