2010-07-16 4 views
3

나는 RemoteActors를 가지고 놀고 있습니다. 이제 RemoteActor를 종료하면 어떻게되는지 궁금합니다. 액터는 RemoteActor.alive 및 RemoteActor.register에서 사용할 수 있습니다. alive와 register 둘 다의 역함수를 찾을 수 없습니다.RemoteActor 등록을 취소합니다

RemoteActor를 올바르게 종료하려면 어떻게합니까?

업데이트

나는 '작은'예를했고, 좀 더 분명하게합니다. 다음 두 프로그램 중 하나라도 종료되지 않으면 JVM이 계속 실행됩니다. 사용자가 만든 모든 액터와 메인이 완성됩니다.

Start A 
Fin A 
A receives M1 
A exits 

그리고 B를위한 것입니다 : A의

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

출력이 디버거는, 프로그램에 대한 말한다

Start B 
B starts 
B receives M3 
B exits 
Fin B 

다음의 4 가지 비 데몬 스레드가 아직까지 있습니다

  • PlainSocketImpl.socketAccept
  • 012 3,516,
  • SocketInputStream.socketRead0
  • ForkJoinScheduler.liftedTree1
  • DestroyJavaVM는

답변

1

Actor .link 당신이 찾고있는 Actor .trapExit인가?

편집 시도해보십시오. 나는 모든 것을 행동 방식으로 옮겼다. 또한 원격 액터들 사이에서 프록시를 전송하는 것이 문제를 일으키는 것처럼 보였습니다. 이 가능한 버그에 대한 토론이 있습니다 : http://www.scala-lang.org/node/6779; Stefan Kuhn의 의견을 참조하십시오.

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) 
    } } 
    } 
} 
+0

아니요, 연결된 다른 액터가 종료되면 Actor.link 및 trapExit를 사용하여 연결된 액터에 알립니다. 지금은 RemoteActors에서 작동하지 않습니다. –

+0

코드를 실행할 수 있으려면 act 메서드 외부에서 RemoteActor.classLoader = getClass(). getClassLoader()를 이동해야했습니다. 그것은 작동합니다. 프록시 전송은 문제의 근원입니다. 감사. –