我正在嘗試讓“詢問”為 Akka Typed 作業。我已經在網上跟蹤了示例,并且我認為我幾乎復制了它們顯示的內容,但是當我嘗試評估“詢問”的回應時出現編譯器錯誤。這是我最小的可重現示例。
SuperSimpleAsker 是一個向 MyWidgetKeeper 演員請求“小部件”的演員。回應是一個表示小部件 ID 的字串。到目前為止,我所做的只是將收到的小部件 ID 記錄為“成功”訊息,稍后將添加更多與該 ID 相關的內容。創建 SuperSimpleAsker 時,傳入 MyWidgetKeeper 的 ActorRef。我省略了創建 Actor 的 Main 程式以保持代碼簡單。
我得到的錯誤是:
type mismatch;
found : Unit
required: widgets.SuperSimpleAsker.Request
此錯誤發生在兩個 logger.* 行(在代碼清單末尾的 Case Failure 和 Case Success 塊內)。
我不明白代碼的哪一部分需要“widgets.SuperSimpleAsker.Request”物件或為什么。
package widgets
import scala.concurrent.duration.DurationInt
import scala.util.{Failure, Success}
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.{ActorRef, Behavior}
import akka.util.Timeout
import com.typesafe.scalalogging.LazyLogging
object MyWidgetKeeper {
sealed trait Request
case class GetWidget(replyTo: ActorRef[Response]) extends Request
sealed trait Response
case class WidgetResponse(widget: String) extends Response
def apply(): Behavior[Request] =
new MyWidgetKeeper().myWidgetKeeper()
}
class MyWidgetKeeper {
import MyWidgetKeeper._
def myWidgetKeeper(): Behavior[Request] = {
Behaviors.receive { (context, message) =>
message match {
case GetWidget(replyTo) =>
replyTo ! WidgetResponse("12345")
Behaviors.same
}
}
}
}
object SuperSimpleAsker {
sealed trait Request
case object DoStuff extends Request
def apply(widgetKeeper: ActorRef[MyWidgetKeeper.Request]): Behavior[Request] =
new SuperSimpleAsker(widgetKeeper).simpleAsker()
}
class SuperSimpleAsker(widgetKeeper: ActorRef[MyWidgetKeeper.Request]) extends LazyLogging{
import SuperSimpleAsker._
import widgets.MyWidgetKeeper.GetWidget
private def simpleAsker(): Behavior[Request] = {
Behaviors.receive { (context, message) =>
message match {
case DoStuff =>
logger.info(f"Doing stuff")
implicit val timeout = Timeout(2000 millis)
context.ask(widgetKeeper, GetWidget)
{
case Failure(exception) =>
logger.error(f"Failed: ${exception.getMessage}")
case Success(response: MyWidgetKeeper.Response) =>
response match {
case MyWidgetKeeper.WidgetResponse(id) =>
logger.info(f"Success: Got Widget# $id")
// Do some more stuff with the widget id
}
}
Behaviors.same
}
}
}
}
uj5u.com熱心網友回復:
在 Akka Typed 中context.ask,傳遞的函式將成功或失敗的請求轉換為發送給參與者的訊息,理想情況下不會產生副作用。
因此,您SuperSimpleAsker必須添加可以將詢問轉換為的訊息:
object SuperSimpleAsker {
sealed trait Request
case object DoStuff extends Request
case class WidgetResponseFor(widgetId: String) extends Request
case object NoWidgetResponse extends Request
def apply(widgetKeeper: ActorRef[MyWidgetKeeper.Request]): Behavior[Request] =
new SuperSimpleAsker(widgetKeeper).simpleAsker()
}
class SuperSimpleAsker(widgetKeeper: ActorRef[MyWidgetKeeper.Request]) extends LazyLogging{
import SuperSimpleAsker._
import widgets.MyWidgetKeeper.GetWidget
private def simpleAsker(): Behavior[Request] = {
Behaviors.receive { (context, message) =>
message match {
case DoStuff =>
logger.info(f"Doing stuff")
implicit val timeout = Timeout(2000 millis)
context.ask(widgetKeeper, GetWidget)
{
case Failure(_) => // there's actually only one possible exception: timed out
NoWidgetResponse
case Success(response: MyWidgetKeeper.Response) =>
WidgetResponseFor(response.widget)
}
Behaviors.same
case WidgetResponseFor(id) =>
logger.info(f"Success: Got Widget# $id")
// Do stuff with the widget id
Behaviors.same
case NoWidgetResponse =>
logger.error("Failed")
Behaviors.same
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/455961.html
