2013-06-15 2 views
1

내가 안전하게 지금까지var를 사용하지 않고 자체 취소 폴러를 구현하는 방법은 무엇입니까?

akka.actor.Cancellable의 인스턴스를 유지하는 VAR를 사용하지 않고 자체 취소 폴러를 구현할 수 있는지 궁금 해요, 난 당신이 아래의 예에서 보는 것과 같은 것을 함께했다.

tick(1, 5, context.system.scheduler.schedule(Duration.Zero, 3 seconds, self, "tick")) 

로 기본적으로 동일합니다 : 그것은 핫 스왑이 폴러가 일정 선 즉,을 발생하기 전에 "틱"메시지가 전달되지 않을 것이라고 가정하는 것이 안전 경우, 궁금 해요

그래서 어떤 경우에는 hotswap이 발생하기 전에 첫 번째 틱이 수신 될 것이라고 생각합니다 ... 생각하십니까?

import akka.actor.{Cancellable, ActorSystem} 
import akka.actor.ActorDSL._ 
import concurrent.duration._ 

object PollerDemo { 
    def run() { 
    implicit val system = ActorSystem("DemoPoller") 
    import system.dispatcher 

    actor(new Act{ 
     become { 
     case "tick" => println("UH-OH!") 
     case "start" => 
      become { 
      tick(1, 5, context.system.scheduler.schedule(Duration.Zero, 3 seconds, self, "tick")) 
      } 
     } 
     def tick(curr:Long, max:Long, poll:Cancellable):Receive = { 
     case "tick" => { 
      println(s"poll $curr/$max") 
      if(curr > max) 
      cancel(poll) 
      else 
      become{ tick(curr + 1, max, poll) } 
     } 
     } 
     def cancel(poll:Cancellable) { 
     println("cancelling") 
     poll.cancel() 
     println(s"cancelled successfully? ${poll.isCancelled}") 
     println("shutting down") 
     context.system.shutdown() 
     } 
    }) ! "start" 

    system.awaitTermination(1 minute) 
    } 
} 
+0

액터 기반 프로그래밍의 요점은 액터의 인스턴스 내에서 액터를 보호함으로써 장기적이고 공유되며 변경 가능한 상태가되는 것입니다. –

+0

흠, 사람들은 제목에 너무 집중하고 있습니다. 내가 너희들을 위해 그것을 고쳐 줄게 – Andrey

답변

3

제 생각에 코드는 괜찮을 것입니다. 배우는 한 번에 하나씩 사서함을 처리합니다. start 메시지를 받으면 사서함에 다른 메시지를 배달하는 타이머를 설정 한 다음 수신 구현을 스왑합니다. start 메시지를 처리하는 동안 수신 스왑을 수행하기 때문에 사서함의 다음 메시지를 처리하기 전에 액터의 수신 동작이 이미 변경되었을 것입니다. 따라서 메시지가 tick 메시지를 처리하기 위해 이동하면 새로운 수신 동작을 사용할 수 있습니다.

당신과 같이 첫 번째 become 내부에 추가 tick 메시지를 전송하여 확인할 수 있습니다 : 여기

become { 
    self ! "tick" 
    tick(1, 5, context.system.scheduler.schedule(Duration.Zero, 3 seconds, self, "tick")) 
} 

될 블록 동안 보낸 메시지가 될 것입니다 묻는 경우 우리가 정말 방정식에서 타이머를 제거하는 이전 수신 또는 새 수신에 의해 처리됩니다. 나는 이것을 실행하지 않았다. 그러나 나의 이해 또는 akka에서,이 똑딱 소리의 양쪽이 아니라 모두은 새로운 받음에 의해 취급되어야한다.

+0

답장을 보내 주셔서 감사합니다. – Andrey

1

실제로 배우와 함께 순수 함수 프로그래밍을 수행 할 수 없습니다. 메시지를 보내는 것은 부작용입니다. 수신 함수가 결과를 반환하지 않기 때문에 메시지를 받으면 모든 액터가 부작용을 일으킬 수 있습니다. 코드에서 수행하는 거의 모든 일이 부작용입니다.

코드 구현시 vars를 피할 수도 있지만 become은 액터 수퍼 클래스에서 var를 변경합니다. context.system.scheduler.schedule은 분명히 부작용이 있으며 어딘가에서 돌연변이가 발생합니다. cancel가하는 모든 일은 부작용입니다. system.awaitTermination(1 minute)은 함수가 아닙니다 ...

+0

나는 akka가 배우들을 어떻게 구현하는지에 관심이 없다. 나는 그들의 사용법에 관심이있다. 행위자는 실제로 메시지를 보낸 사람에게 회신하여 값을 반환합니다. 내 실제 질문에 대한 답을 드릴까요? system.awaitTermination은 확실히 최신 [akka api] (http://doc.akka.io/api/akka/2.0/akka/actor/ActorSystem.html)를 확인하는 기능입니다. – Andrey

+0

@Andrey 그들은 객체가 아니라 숨겨진 상태의 메소드입니다. – jwinandy

+0

@stew 액터 내부를 기능적 스타일로 작성할지 여부는 메시지를 보내는 것이 부작용인지 여부와 관계없이 의미있는 선택입니다. 일반적으로 행동 스택이 하나 인 행위자의 매우 적은 수의 가상 변수에 변경 가능성을 제한하는 것이 여러면에서 도움이됩니다. Akka는 고의적으로 독단적이지 않습니다. –

관련 문제