首页 文章

Scala,Akka:特征问题中对象的模式匹配

提问于
浏览
0

美好的一天 . 我正在制作一个简单的程序来检查某些服务器状态并面临模式匹配的问题 . 这是代码:入口点:

object Run extends App with StateActor.Api{
  private implicit val system = ActorSystem()
  implicit val blockingDispatcher: MessageDispatcher = system.dispatchers.lookup("blocking-dispatcher")
  protected val log: LoggingAdapter = Logging(system, getClass)
  protected implicit val materializer: ActorMaterializer = ActorMaterializer()

  import scala.concurrent.duration._
  implicit val timeout = Timeout(17 seconds)

  val listener = system.actorOf(StateActor.props)
  system.scheduler.schedule(
    0 milliseconds,
    5 minutes,
    listener,
    Ping
  )
}

演员:

class StateActor(implicit val blockingDispatcher: MessageDispatcher) extends Actor with StateActor.Api with ActorLogging {

  import akka.pattern.pipe
  private val formatter = JSONFormat.defaultFormatter
  private val mHookUrl = ...

  var mState: State = UNDEFINED
  override def receive: Receive = {
    case Ping =>
      log.debug("Ping")
      Future(Http("http://...").timeout(15000, 15000).asString)
        .map {
          case HttpResponse(_, 200, _) => UpResponse
          case HttpResponse(body, code, _) => DownResponse(s"Code: $code, body:\n $body")
          case rest => DownResponse(s"Undefined object: ${rest.toString}")
        } recover { case e => DownResponse(e.getMessage) } pipeTo self

    case UpResponse =>
      if (mState == DOWN || mState == UNDEFINED) {
        mState == UP
        reportToSlack("Client Up")
      }

    case DownResponse(reason) =>
      if (mState == UP || mState == UNDEFINED) {
        mState == DOWN
        reportToSlack(s"Client DOWN!\n Reason: $reason")
      }
    case other =>
      println(other)
      println(other.getClass)
  }

  def reportToSlack(message: String): Unit = {
    ...
  }
}

object StateActor {
  trait Api {
    case object Ping

    sealed trait State
    case object UP extends State
    case object DOWN extends State
    case object UNDEFINED extends State

    sealed trait StateMessage
    case object UpResponse extends StateMessage
    case class DownResponse(reason: String) extends StateMessage
  }

  def props(implicit blockingDispatcher: MessageDispatcher) = Props(new StateActor())
}

正如您所看到的,我将所有消息和其他内容放在“StateActor”伴随对象中的特征“API”中 . 但是当调度程序向actor发送“Ping”时,它匹配'case other',而不是'case Ping' . 只需将“案例对象Ping”从特征和伴随对象中移出并使其成为“独立”对象即可解决问题 . 像这样:

case object Ping
object StateActor {
      trait Api {
        ...
    }
    ...
}

但是为什么它在内在特质时不起作用?特征模式中的所有其他案例类和对象都匹配得很好 .

1 回答

  • 2

    RunStateActor 都分别扩展了特征,因此每个特征都有自己的 Ping 对象,它们不应该匹配 . 其他消息匹配的唯一原因是因为 StateActor 正在将它们发送给自己!它甚至不适用于两个不同的 StateActor 实例 .

    代替

    从特征和伴侣对象中移出'case object Ping'

    你应该 Api object 并通过导入消息来访问它们: import StateActor.Api._ 而不是 extends StateActor.Api (或直接将它们放入 object StateActor ) .

相关问题