簡體   English   中英

Akka模塊化消息發送功能

[英]Akka modular message sending function

我正在使用Spray + Akka(我想說“框架”,但他們想被稱為“圖書館”)。 我收到一個REST調用,並返回響應。 但是,我發現我的處理有些重復。 這是我從兩個API收到POST請求時的兩個塊:

post {
                entity(as[JObject]) { company =>
                  if (AuthInfo.rejectedOrNot) {
                    val response = (secCompanyActor ? jObjectFromWeb(company))
                      .mapTo[TransOk]
                      .map(result => result.succeedOrNot match {
                      case true => (OK, "transaction successful")
                      case false => (BadRequest, result.errorMessage)
                    }).recover { case _ => (BadRequest, "An error has occurred! We will fix this")}
                    complete(response)

                  } else {
                    complete(Unauthorized, "Please use HTTP header to authorize this command.")
                  }
                }

另一個塊非常相似,但是唯一的區別是不是發送jObjectFromWeb(...) ,而是發送以下消息: jObjectFromComputer(...)

我想創建一個函數,在其中傳遞消息,然后從該函數發送消息,但是Akka的消息不是TYPED! 我從無類型的消息中了解其原理,並且我沒有要求任何東西,但是我想要一個很好的解決方案。 是的,一種解決方案是傳入諸如sendMessageToActor(actor, "jObjectFromWeb")類的字符串sendMessageToActor(actor, "jObjectFromWeb")然后在實際函數中使用模式匹配來發送相應的消息。

但這有點難看,而且不是模塊化的(如果我要發送10條消息該怎么辦?)。

有什么辦法嗎? 我不太熟悉Java的反射,但是如果我可以通過字符串找到消息用例類/對象,那將非常好。


這是我的Akka actor實施方面:

class SECCompanyActor extends Actor with ActorLogging {
  import com.mturk.tasks.SECcompany.SECCompanyProtocol._

  def receive = {

    case jObjectFromCasper(jObject) =>
      //Do some logic
      sender ! TransOk(result._1, result._2, result._3)

    case jObjectFromWeb(jObject) =>
      // Do some other logic
      sender ! TransOk(result._1, result._2, result._3)
  }

這是我的Akka訊息:

object SECCompanyProtocol {
  case class jObjectFromCasper(jObject: JObject)
  case class TransOk(company: Option[Company.Company], succeedOrNot: Boolean, errorMessage: Option[String])
  case class jObjectFromWeb(jObject: JObject)
}

這個怎么樣:

def doPost(messageConstructor: Company => AnyRef): Route = {
  entity(as[JObject]) { company =>
    if (AuthInfo.rejectedOrNot) {
      val response = (secCompanyActor ? messageConstructor(company))
        .mapTo[TransOk]
        .map(result => result.succeedOrNot match {
          case true => (OK, "transaction successful")
          case false => (BadRequest, result.errorMessage)
        }).recover { case _ => (BadRequest, "An error has occurred! We will fix this")}
      complete(response)
    } else {
      complete(Unauthorized, "Please use HTTP header to authorize this command.")
    }
  }
}    

post {
  doPost(jObjectFromWeb.apply)
}

如您的評論所述,當jObjectFromWeb / jObjectFromComputer是案例類時,此方法有效。 jObjectFromWeb.apply對應案例類的伴侶對象的apply方法,該對象是為案例類自動創建的。 類型安全性更高的設計將從單個特征繼承兩個案例類:

trait GenericJObject {
  val company: Company
}

case class JObjectFromWeb(override val company: Company) extends GenericJObject

case class JObjectFromComputer(override val company: Company) extends GenericJObject

def doPost(messageConstructor: Company => GenericJObject): Route = {
...
}

同樣,對於可維護性和理解您的代碼以遵守Scala編碼約定(類名以大寫字母開頭)會更好,否則可能會引起混淆,並假定jObjectFromXXX是方法而不是case類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM