Akka拦截具有可堆叠行为的接收 [英] Akka intercepting receive with stackable behavior

查看:115
本文介绍了Akka拦截具有可堆叠行为的接收的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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拦截具有可堆叠行为的接收的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆