美好的一天。我正在制作一个简单的程序来检查某些服务器状态并面临模式匹配的问题。 这是代码: 切入点:
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 {
...
}
...
}
但是为什么它在内在特质时不起作用?特征模式中的所有其他案例类和对象都匹配得很好。
答案 0 :(得分:2)
Run
和StateActor
都会分别扩展特征,因此每个特征都有自己的Ping
对象,并且它们不应该匹配。其他消息匹配的唯一原因是因为StateActor
正在将它们发送给自己!它甚至不能用于两个不同的StateActor
个实例。
而不是
移动'案例对象Ping'从特质和伴侣对象出来
您应该Api
object
并通过导入消息来访问消息:import StateActor.Api._
而不是extends StateActor.Api
(或直接将其放入object StateActor
)