Akka Typed에서 Ask Pattern을 사용하는 데 약간의 문제가 있습니다. 액터 외부에서 메시지를 보내려고 하고이 예제 를 따르려고했습니다 . 그러나 내 설정이 예제와 약간 다르다고 생각합니다.
object SimulatorManager {
fun create(): Behavior<SimulatorManagerMessage> {
val state = ... // initialize state
return waitingToStartSimulation(state)
}
private fun waitingToStartSimulation(state: SimulatorManagerState): Behavior<SimulatorManagerMessage> {
return Behaviors.receive { context, message ->
when (message) {
is StartSimulation -> {
// start simulation and update state
waitingToStartSimulation(state)
}
else -> Behaviors.same()
}
}
}
}
sealed class SimulatorManagerMessage
data class StartSimulation(
val consumer: ConsumerCredentials,
val storeId: Long,
val itemId: Long,
val simTimeIncrement: Double,
val realTimeIncrement: Double,
) : SimulatorManagerMessage()
액터 시스템 외부에서 StartSimulation
메시지 를 보내려고합니다 SimulatorManager
. 그러나 replyTo
함수 매개 변수 에 무엇을 입력해야할지 고민하고 있습니다.
class SimulatorController(
val systemRef: ActorSystem<SimulatorManagerMessage>,
private val simManagerRef: ActorRef<SimulatorManagerMessage>
) {
fun startSimulation(request: StartSimulationRequest) {
val msg = request.toMessage()
val result = AskPattern.ask<SimulatorManagerMessage, SimulatorController>(
simManagerRef,
{ replyTo -> }, // what should go here?
Duration.ofSeconds(15),
systemRef.scheduler()
)
}
}
매개 변수의 유형이이어야한다고 Function<ActorRef<SimulatorController!>!, SimulatorManagerMessage!>!
말하지만 이와 같은 함수를 만드는 방법을 모르겠습니다. 어떤 도움을 주시면 감사하겠습니다!
이 replyTo ->
함수는 보낼 메시지를 구성하고 응답으로 메시지를받을 액터에 대한 참조를 삽입합니다.
이는 비 동기화하기 위해 요청 패턴이 효과적으로 수행하는 작업이 다음과 같기 때문입니다.
고전적인 (유형이 지정되지 않은) Akka에서 메시지는 수신자 sender
가 모든 메시지를 결정할 수 있도록 구성 될 것이므로 요청 패턴은 매우 간단합니다 (액터로부터 요청을 보낼 때 결과 미래에주의해야합니다. 당신이 할 수있는 유일한 안전한 일은 메시지를 수정하고 그것을 당신의 우편함에 파이프하는 것입니다).
Akka Typed에서는 ActorRef
이제 보낼 수있는 메시지를 제어 하기 때문에 sender
사용할 수 없습니다. 따라서 이제 프로토콜을 구성하는 메시지에서 예상되는 응답의 유형을 명시 적으로 모델링해야합니다.
이것이 내가 작성한 첫 번째 Kotlin이라고 고백하는 곳이지만 다음과 같은 내용이있을 수 있습니다.
sealed class GradebookCommand
data class GetGradeFor(val student: String, val replyTo: ActorRef<GradeForStudent>): GradebookCommand()
data class GradeForStudent(val student: String, val score: Int, val outOf: Int)
sealed class GradebookRouterCommand
data class GetGradebookActorFor(val classId: String, val replyTo: ActorRef<GradebookIs>): GradebookRouterCommand()
data class GradebookIs(val classId: String, val gradebookActor: ActorRef<GradebookCommand>)
그 가정하는 것은 그래서 gradebookRouter
입니다 ActorRef<GradebookRouterCommand>
, 당신은에 물어 것
val classId: String = "asdf"
val gradebookFuture: CompletionStage<GradebookIs> =
AskPattern.ask<GradebookRouterCommand, GradebookIs>(
gradebookRouter,
{ replyTo -> GetGradebookActorFor(classId, replyTo) },
Duration.ofSeconds(15),
systemRef.scheduler
)
gradebookFuture
최종적으로 답장을 보내 게 된 GradebookIs
메시지 로 완성 될 것입니다 gradebookRouter
(이 표현을 사용하는 이유 중 하나 replyTo
는 작업을 다른 배우에게 위임 할 수 있다는 것입니다. Akka Classic에서도 가능하지만 엉망으로 만들기 쉬운 보낸 사람을 보존하는 데 약간의 미묘함이 있습니다.)
// This is perhaps where my Kotlin/Java futures code goes off the rails
val student: String = "Parry Hotter"
val gradeFuture: CompletionStage<GradeForStudent> =
gradebookFuture.thenComposeAsync({ gradebook ->
AskPattern.ask<GradebookCommand, GradeForStudent>(
gradebook,
{ replyTo -> GetGradeFor(student, replyTo) },
Duration.ofSeconds(15),
systemRef.scheduler
)})
면책 조항 : Scala와 관련된 Java / Kotlin 유형 시스템의 미묘함 (예 : 공분산 / 반반 변성)으로 인해 해당 코드가 작동하지 않을 수 있지만, 이것이 합리적으로 명확 해지기를 바랍니다.
TL; DR : 회신 주소로 사용되는 메시지에 필드가 있는지 확인하십시오. replyTo
그것은 확실히 관습으로 등장했지만 이름을 붙일 필요는 없습니다 .
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다