Akka和Scala新手,请随时编辑问题,以明确表达我对Scala和Akka的意图。
Akka and Scala newbie here, please feel free to edit the question as necessary in order to clearly articulate my intent in the domain of Scala and Akka.
显示代码片段,这是我要解决的问题:本质上,我想为我的团队开发一个通用模块,供他们在使用Akka actor开发应用程序时使用。我想允许他们混合一个特征,该特征将在运行时扩展其接收功能,主要用于记录目的。我遇到了编译错误,我将在后面进行解释。
Before I show code snippets, here's the problem I want to solve: I essentially want to develop a common module for my team to use when they're developing their applications using Akka actors. I want to allow them to mixin a trait which will extend their receive functionality at runtime, mainly for logging purposes. I'm running into compile errors, which I'll explain soon.
但是首先,以一个简单的main为例:
But first, take for example, a simple main:
object Test extends App { val system = ActorSystem("system") val myActor = system.actorOf(Props(new MyActor), "myActor") myActor ! "Hello world!" }以下是一个演员的示例实现,团队成员可以在其应用程序中实现:
Here's an example implementation of an actor that a team member might implement in his application:
class MyActor extends Actor with ActorLogger { override def receive: Receive = { case msg => { log.info("testing ...") } case _ => throw new RuntimeException("Runtime Ex") } }我将如何为他们提供一个共同的特征来进行混合的示例:
And here's an example of how I would provide a common trait for them to mixin:
trait ActorLogger extends Actor { val log: DiagnosticLoggingAdapter = Logging(this) abstract override def receive: Receive = { case msg: Any => { if (msg.isInstanceOf[String]) { println("enter") log.mdc(Map[String, Any]("someKey" -> 123)) super.receive(msg) log.clearMDC() println("exit") } } case _ => throw new RuntimeException("Runtime Ex") } }正如您所看到的,如果消息恰好是字符串,我正在尝试将数据添加到MDC(实际上是一个基本示例,我会检查自己的自定义类型)。
As you can see, I'm trying to add data to an MDC if the message so happens to be String (a basic example, in reality, I would check for some custom type of our own).
我得到的错误是:
Error:(29, 16) overriding method receive in trait ActorLogger of type => MyActor.this.Receive; method receive needs `abstract override' modifiers override def receive: Receive = { ^这是怎么了?可堆叠特征是否有权实现这样的目标?如果不是,最惯用的方法是什么?
What's wrong here? And is stackable traits the right to go away to achieve something like this? If not, what is the most idiomatic way?
更普遍的是,除了拦截器模式之外,还有其他模式在应用吗?
More generally, is there another pattern being applied here besides "interceptor" pattern?
感谢所有帮助!
推荐答案一个没有 akka的解决方案包:
import akka.actor.{Actor, ActorSystem, Props} trait MyActorExtension extends Actor { def receiveExtension: Receive = PartialFunction.empty } abstract class MyActor extends MyActorExtension { protected def receiveMsg: Receive def receive: Receive = receiveExtension orElse receiveMsg } trait ActorLogger1 extends MyActor with MyActorExtension { abstract override def receiveExtension = { case msg => println(s"********** Logging # 1: $msg") super.receiveExtension.applyOrElse(msg, receiveMsg) } } trait ActorLogger2 extends MyActor with MyActorExtension { abstract override def receiveExtension = { case msg => println(s"########## Logging # 2: $msg") super.receiveExtension.applyOrElse(msg, receiveMsg) } } class SpecificActor extends MyActor with ActorLogger1 with ActorLogger2 { def receiveMsg = { case someMsg => println(s"SpecificActor: $someMsg") } } object Test extends App { val system = ActorSystem("system") val mySpecificActor = system.actorOf(Props(new SpecificActor), "SpecificActor") mySpecificActor ! "Hello world!" }####记录#2:世界您好!
****** 记录#1:Hello world!
#### Logging # 2: Hello world!
****** Logging # 1: Hello world!
SpecificActor:Hello world !
SpecificActor: Hello world!
更多推荐
Akka拦截具有可堆叠行为的接收
发布评论