복붙노트

[SCALA] 어떻게 특정 유형에 배우 메시지를 제한하려면?

SCALA

어떻게 특정 유형에 배우 메시지를 제한하려면?

Akka에서는, RPC 스타일의 프로그래밍 모델을 사용하는 "형식화 된 배우"API를 사용하는 것보다 다른 특정의 정적 유형으로 배우에 메시지를 제한하는 방법은 무엇입니까?

나는 배우의 경계에서 멀리 정적 유형의 안전을 던지는없이 Akka와 메시지 전달 스타일을 사용할 수 있습니까?

예를 들어, 나는 다음과 같은 코드를 사용하고 싶습니다 :

sealed abstract class FooMessage
case object Foo extends FooMessage
case object Bar extends FooMessage

class FooActor extends Actor[FooMessage] {
  def receive = {
    case Foo => () // OK

    // Would raise a compiler error:
    // case s: String => error("Can't happen, String is not a subtype of FooMessage") 

  }
}

val fooActor = actorOf[FooActor]
fooActor ! Foo // OK

// Won't compile:
fooActor ! "Hello"

아마도 하나의 시스템 수준 메시지 (종료 등) 할 수 있도록 하나 같은 구조를 일부 기본 특성을 확장하거나해야 할 것입니다.

해결법

  1. ==============================

    1.그럼 당신은 크게 ActorRegistry 같은 값을 감소 할 액터 심판,에 메시지 유형을 인코딩해야 할 것이다.

    그럼 당신은 크게 ActorRegistry 같은 값을 감소 할 액터 심판,에 메시지 유형을 인코딩해야 할 것이다.

    또한, (배우 모델에 기본입니다) "가"와 같은 강력한 역학과 메시지를 입력 덜 중요합니다.

    메시지가 현재 동작과 일치하지 않을 때 Akka하지 누출 메모리를 수행하기 때문에, "잘못된"배우에 "잘못된"메시지 전송과 같은 위험이 없다.

    그냥 평범한 배우로 RPC로 무효 방법, 미래의 반환 형식이! 다른 반환 형식!있는 통화 또한, 배우 당신이 RPC없는 그 정적, 사용 TypedActor을 (만들고 싶어 그렇다면, 자연 동적으로, 그것은이다 에 기반 !!)

    일반적인 연습은 배우가 아주 많이 더 쉽게받을 수있는 것을 알 수있다 액터의 동반자 객체에서받을 수있는 메시지를 선언하는 것입니다.

    그 도움을합니까?

  2. ==============================

    2.스칼라 다음 stdlib에서 (내가 기억하는대로, 수신 중첩 된 지원하지 않기 때문에, Akka 적용되지 않습니다) 유형이 지정되지 않은 기본 배우를 만들기위한 변명이 있었다. 리프트, 나아가서, 지원은 아웃 - 오브 - 박스 배우를 입력했습니다.

    스칼라 다음 stdlib에서 (내가 기억하는대로, 수신 중첩 된 지원하지 않기 때문에, Akka 적용되지 않습니다) 유형이 지정되지 않은 기본 배우를 만들기위한 변명이 있었다. 리프트, 나아가서, 지원은 아웃 - 오브 - 박스 배우를 입력했습니다.

    그러나 채널을 사용하여, 그것은 다음 stdlib와 강력한 형식의 배우를 작성하는 것은 여전히 ​​가능합니다 :

    object TypedActor {
    
      def apply[A](fun: PartialFunction[A, Any]): OutputChannel[A] = {
        val sink = new SyncVar[Channel[A]]
        actor {
          val in = new Channel[A](self)
          sink set in
          loop {
            in react { case any => reply(fun(any)) }
          }
        }
        sink.get
      }
    
    }
    
    sealed abstract class FooMessage
    case object Foo extends FooMessage
    case object Bar extends FooMessage
    
    object Test {
    
      val fooActor = TypedActor[FooMessage]{
        case Foo => println("OK")
      }
    
      fooActor ! Foo 
      fooActor ! "Hello!" // doesn't compile -> Type mismatch; found: String("Hello!"); required: FooMessage;
    
    }
    
  3. ==============================

    3.실제로 입력하지 매우 유용으로 단지 하나의 유형이하는 배우를 제한. 내 마음에 더 유용 얼마나 엄격한 타입 방식으로 가능한 입력을 표시하는 것입니다.

    실제로 입력하지 매우 유용으로 단지 하나의 유형이하는 배우를 제한. 내 마음에 더 유용 얼마나 엄격한 타입 방식으로 가능한 입력을 표시하는 것입니다.

    배우의 엄격한 타입 입력 (SynapseGrid)에 대한 접근 방법이 있습니다 :

    case class Contact[T](...)
    case class Signal[T](contact:Contact[T], data:T)
    

    귀하의 경우 인터페이스는 하나의 입력 접점으로 구성

    val FooInput = contact[FooMessage]("FooInput")
    

    SynapseGrid 내에서 신호의 프레임 워크 처리는 빌더로 정의된다 :

    class FooActorBuilder extends SystemBuilder {
      inputs(FooInput, OtherInput)
      FooInput.foreach(fooMessage => () //OK
      )
      OtherInput.foreach(...)
    }
    

    분명히 하나는 호환되지 않는 유형의 신호를 생성 할 수 없습니다. 따라서 우리는 컴파일 시간 검사가 있습니다. SynapseGrid에서 신호 및 연락처 작업을위한 DSL있다. 예를 들어, 외부에서 푸 또는 바을 보내 :

    val SomeOtherContact = contact[Boolean]("SomeOtherContact")
    SomeOtherContact.map(flag => if(flag) Foo else Bar) >> FooInput
    

    물론 하나는 단순히 메시지를 보낼 수 있습니다 :

    val inputMessage = Signal(FooInput, Foo)
    actor ! inputMessage
    
  4. ==============================

    4.Akka의 Akka의 형식화 된 채널 지원하도록했다이를 해결하지만, (주석에 따라 이미 2.3 버전에서 Akka에서 제거 된) 것 같은데.

    Akka의 Akka의 형식화 된 채널 지원하도록했다이를 해결하지만, (주석에 따라 이미 2.3 버전에서 Akka에서 제거 된) 것 같은데.

    Akka 2.2.3에 대한 설명서에 나와있는 지원의 어려움이 메시지를 전송하고 응답이 입력 좋은 "디자인 배경"섹션 것이다.

    롤랜드 쿤에 의해 좋은 NEScala의 이야기도 있습니다, Akka 형식화 된 채널 : 매크로로 구현 형 계산 ([유튜브] / [슬라이드]), 즉 나와있는 입력 채널의 구현입니다.

  5. from https://stackoverflow.com/questions/5547947/how-to-restrict-actor-messages-to-specific-types by cc-by-sa and MIT license