2016-12-19 5 views
1

현재 스칼라 코드에서 akka Actor 시스템을 사용하고 있습니다. 부모 배우와 배우가 있습니다. 내가하고 싶은 일은 부모 배우에게서리스트를 시작하고 배우를 배우게하는 것입니다 :스칼라의 akka 배우 시스템 내의 전역 변수

i) 새로운 요소를 생성하고이를 부모 배우에게 보내면 누가 그 요소를리스트에 첨부 할 것입니다. ii) 언제든지 목록 요소에 액세스하십시오.

어떻게 두 번째 부분을 얻을 수 있습니까?

답변

-1

글쎄, 나는 해결책을 찾을 수 있었다.

부모 액터 내에 변수를 만들고이를 구성 매개 변수로 하위 액터에 전달하면이 변수의 모든 변경 사항을 대체하지 않으면 볼 수 있습니다. 나는 잘못된 예를 따르는 올바른 예를 들어 설명 할 것이다.

class ParentActor(/*constructors here*/) extends Actor{ 
    val list =ListBuffer[Int](1,2) 
    child = new ChildActor(list //+other constructors) 

    list=ListBuffer[Int](1,2,3) // **wrong** child will see list=List(1,2) 
    list+=3   // **right** child will see list=List(1,2,3) as wanted 

}

class ChildActor(list : ListBuffer[Int] /*++ otherconstructors here*/) extends Actor{ 

     list=ListBuffer[Int](1,2,3,4) // **wrong** parent will see list=List(1,2,3) 
     list+=4   // **right** child will see list=List(1,2,3,4) as wanted 

}

+0

이 솔루션은 Akka 안티 패턴 및 권장하지 않습니다. 우선, ListBuffer는 쓰레드에 안전한 콜렉션이 아니라는 것에 주목하자. 둘째, 스레드 안전 컬렉션을 선택하더라도 직렬화가 불가능하기 때문에 위치 투명성이 위배됩니다. 여기에서 더 읽기 http://manuel.bernhardt.io/2016/08/02/akka-anti-patterns-shared-mutable-state/ –

1

학부모가 답장 할 수있는 특정 메시지를 선택하여 내부 상태를 공개 할 수 있습니다. 동일한 동작이 var queue 내부에 부모를 유지하는 대신 context.become + 재귀를 사용하여 달성 될 수 있다는

import scala.collection.immutable.Queue 

    class Parent extends Actor { 
    import Parent._ 

    // TODO: start children here 

    override def receive: Receive = receiveElements(Queue.empty[Element]) 

    def receiveElements(acc: Queue[Element]): Receive = { 
     case [email protected] => context.become(receiveElements(acc :+ e)) 
     case GetElements => sender ! acc 
    } 
    } 

    object Parent { 
    case class Element(s: String) 
    case object GetElements 
    } 

참고 : 아래의 예를 참조.

큐를 플러시하는 방법을 설계하지 않으면 잠재적으로 OOME이 발생할 수 있습니다.

+0

문제는 실행하는 동안 나는이 목록에 액세스 할 수 있도록 할 것입니다. 내 자식 배우가 "시작"메시지를 받고, 함수를 실행하고 내부 함수가 목록에 액세스 할 수 있기를 바랍니다. 첫 번째 메시지가 처리 될 때까지 기다렸다가 두 번째 메시지를 처리하고 싶지 않습니다. – Noowada

+1

간단히 말하면 : 불가능합니다. 이것은 Akka의 모든 교리를 위반합니다. – Ryan

+0

재정의 질문 : http://stackoverflow.com/questions/41247523/how-to-periodically-check-an-actor-mailbox-and-alter-variables-in-scala – Noowada

3

은 메시지 전달을 사용해야합니다. 두 배우 사이에 어떤 종류의 변경 가능한 상태를 공유하면 Akka가 제공하는 모든 보장을 위반하게됩니다.

또는 대리인을 자녀와 상위 액터간에 공유 할 수 있습니다. 그러면 동기 읽기를 허용하면서 목록에 대한 업데이트가 선형화됩니다.

+0

나는 내가 무엇을 더 대표하게 될지에 관해서 명상을 변경했습니다. 원하는 : – Noowada

+0

http://stackoverflow.com/questions/41247523/how-to-periodically-check-an-actor-mailbox-and-alter-variables-in-scala – Noowada