3

私はRemoteActorsで遊んでいます。RemoteActorをシャットダウンするとどうなるのだろうか。アクターは、R​​emoteActor.aliveおよびRemoteActor.registerで使用可能になりました。生きていると登録するという両方の逆を見つけることができません。

RemoteActorを適切にシャットダウンするにはどうすればよいですか?

アップデート

より明確にするために、私は「小さな」例を作成しました。次の2つのプログラムはどちらも終了せず、JVMは実行を継続します。ユーザーが作成したすべてのアクターとメインが終了します。

package test

import scala.actors.{OutputChannel, AbstractActor, Actor} , Actor._
import scala.actors.remote.RemoteActor , RemoteActor._


object ActorTestA{
  def main(args :Array[String]) {
    RemoteActor.classLoader = getClass().getClassLoader()
    println("Start A")
    val a = new A().start
    println("Fin A")
  }
}

object ActorTestB{
  def main(args :Array[String]) {
    RemoteActor.classLoader = getClass().getClassLoader()
    println("Start B")
    val b = new B().start
    b !? 'start
    println("Fin B")
  }
}

case class M1(sendRef :AbstractActor, m2 :M2)
case class M2(v1:String, v2 :String, sendRef :AbstractActor)
case class M3(m2 :M2)

object A { val portToUse = 20000 }
class A extends Actor {
  alive(A.portToUse)
  register('A, this)
  val proxy = select(actors.remote.Node("localhost", A.portToUse), 'A)

  def act = { 
    loop { react {
      case M1(sendRef, m2) =>
        println("A receives M1")
        sendRef ! M3(m2)
        self ! 'exit
      case 'exit => 
        println("A exits")
        exit
      case any => println("Unknown Msg: "+any)
    } } 
  }
}


class B extends Actor {
  val portToUse = 20001 
  alive(portToUse)
  register('B, this)
  val proxy = select(actors.remote.Node("localhost", portToUse), 'B)

  var resultTo :OutputChannel[Any] = _
  def act = { 
    loop { react {
      case 'start => 
        println("B starts")
        val a = select(actors.remote.Node("localhost", A.portToUse), 'A)
        a ! M1(proxy, M2("some","val", proxy))
        resultTo = sender
      case M3(M2(v1,v2,sendRef))=>
        println("B receives M3")
        resultTo ! sendRef
        self ! 'exit
      case 'exit => 
        println("B exits")
        exit
      case any => println("Unknown Msg: "+any)
    } } 
  }
}

Aの出力は次のとおりです。

Start A
Fin A
A receives M1
A exits

そしてBの場合:

Start B
B starts
B receives M3
B exits
Fin B

デバッガーは、Aプログラムについて、次の4つの非デーモンスレッドがまだ稼働していると言います。

  • PlainSocketImpl.socketAccept
  • SocketInputStream.socketRead0
  • ForkJoinScheduler.liftedTree1
  • JavaVMを破棄します
4

1 に答える 1

1

Actor.linkとActor.trapExitはあなたが探しているものですか?

編集これを試してみてください。私はすべてをactメソッドに移しました。また、リモートアクター間でプロキシを送信すると問題が発生するようです。この可能性のあるバグについての議論がここにあります:http ://www.scala-lang.org/node/6779 ; StefanKuhnからのコメントを参照してください。

package test

import scala.actors.{OutputChannel, AbstractActor, Exit, Debug, Actor} , Actor._
import scala.actors.remote.RemoteActor , RemoteActor._


object ActorTestA{
  def main(args :Array[String]) {
    println("Start A")
    val a = new A().start
    println("Fin A")
  }
}

object ActorTestB{
  def main(args :Array[String]) {
    println("Start B")
    val b = new B().start
    b ! 'start
    println("Fin B")
  }
}

case class AA(hostname: String, port: Int, symbol: Symbol) {
  def proxy = select(actors.remote.Node(hostname, port), symbol)
}
case class M1(sendRef :AA, m2 :M2)
case class M2(v1:String, v2 :String, sendRef :AA)
case class M3(m2 :M2)

object A { val portToUse = 20000 }
class A extends Actor {
  def act = { 
    alive(A.portToUse)
    register('A, this)
    RemoteActor.classLoader = getClass().getClassLoader()
    val proxy = select(actors.remote.Node("localhost", A.portToUse), 'A)

    loop { react {
      case M1(sendRef, m2) =>
        println("A receives M1")
        sendRef.proxy ! M3(m2)
        self ! 'exit
      case 'exit => 
        println("A exits")
        exit
      case any => println("Unknown Msg: "+any)
    } } 
  }
}


class B extends Actor {
  def act = { 
    RemoteActor.classLoader = getClass().getClassLoader()
    val portToUse = 20001 
    alive(portToUse)
    register('B, this)
    var proxy = AA("localhost", portToUse, 'B)
    var resultTo :Option[OutputChannel[Any]] = None

    loop { react {
      case 'start => 
        println("B starts")
        val a = select(actors.remote.Node("localhost", A.portToUse), 'A)
        a ! M1(proxy, M2("some","val", proxy))
        resultTo = Some(sender)
      case M3(M2(v1,v2,sendRef))=>
        println("B receives M3") 
        resultTo match {  
          case Some(ch) => ch ! sendRef.proxy;  
          case None => println("ch missing!?")
        }
        self ! 'exit 
      case 'exit => 
        println("B exits")
        exit
      case any => println("Unknown Msg: "+any)
    } } 
  }
}
于 2010-07-16T15:17:59.203 に答える