java akka 并发,Akka整合并发数据库请求

在Jamie Allen阅读Effective Akka之后,我将尝试应用他的“Cameo”模式建议 .

我认为我创造的东西会起作用,但听起来并不像杰米在谈话中的评论那样最好 . 我将更新/编辑回到我已经实现(或尝试)的帖子 .

Summary Actor (Cameo Actor):

object SummaryResponseHandler {

case object DbRetrievalTimeout

def props(mongoDb: ActorRef, redisDb: ActorRef, originalSender: ActorRef): Props = {

Props(new SummaryResponseHandler(mongoDb, redisDb, originalSender))

}

}

class SummaryResponseHandler(mongoDb: ActorRef, redisDb: ActorRef,

originalSender: ActorRef) extends Actor with ActorLogging {

import SummaryResponseHandler._

var mongoSummary, redisSummary: Option[String] = None

def receive = LoggingReceive {

case MongoSummary(summary) =>

log.debug(s"Received mongo summary: $summary")

mongoSummary = summary

collectSummaries

case RedisSummary(summary) =>

log.debug(s"Received redis summary: $summary")

redisSummary = summary

collectSummaries

case DbRetrievalTimeout =>

log.debug("Timeout occurred")

sendResponseAndShutdown(DbRetrievalTimeout)

}

def collectSummaries = (mongoSummary, redisSummary) match {

case (Some(m), Some(r)) =>

log.debug(s"Values received for both databases")

timeoutMessager.cancel

sendResponseAndShutdown(DataSetSummary(mongoSummary, redisSummary))

case _ =>

}

def sendResponseAndShutdown(response: Any) = {

originalSender ! response

log.debug("Stopping context capturing actor")

context.stop(self)

}

import context.dispatcher

val timeoutMessager = context.system.scheduler.scheduleOnce(

250 milliseconds, self, DbRetrievalTimeout)

}

class SummaryRetriever(mongoDb: ActorRef, redisDb: ActorRef) extends Actor with ActorLogging {

def receive = {

case GetSummary(dataSet) =>

log.debug("received dataSet")

val originalSender = sender

val handler = context.actorOf(SummaryResponseHandler.props(mongoDb,redisDb, originalSender), "cameo-message-handler")

mongoDb.tell(GetSummary(dataSet), handler)

redisDb.tell(GetSummary(dataSet), handler)

case _ => log.debug(s"Unknown result $GetSummary(datset)")

}

}

Common:

case class GetSummary(dataSet: String)

case class DataSetSummary(

mongo: Option[String],

redis: Option[String]

)

case class MongoSummary(

summary: Option[String]

)

case class RedisSummary(

summary: Option[String]

)

trait MongoProxy extends Actor with ActorLogging

trait RedisProxy extends Actor with ActorLogging

Mock Stubs:

class MongoProxyStub extends RedisProxy {

val summaryData = Map[String, String](

"dataset1" -> "MongoData1",

"dataset2" -> "MongoData2")

def receive = LoggingReceive {

case GetSummary(dataSet: String) =>

log.debug(s"Received GetSummary for ID: $dataSet")

summaryData.get(dataSet) match {

case Some(data) => sender ! MongoSummary(Some(data))

case None => sender ! MongoSummary(Some(""))

}

}

}

class RedisProxyStub extends MongoProxy{

val summaryData = Map[String, String](

"dataset1" -> "RedisData1",

"dataset2" -> "RedisData2")

def receive = LoggingReceive {

case GetSummary(dataSet: String) =>

log.debug(s"Received GetSummary for ID: $dataSet")

summaryData.get(dataSet) match {

case Some(data) => sender ! RedisSummary(Some(data))

case None => sender ! RedisSummary(Some(""))

}

}

}

Boot (You should use test, but was just wanting to run from boot):

object Boot extends App{

val system = ActorSystem("DbSystem")

val redisProxy = system.actorOf(Props[RedisProxyStub], "cameo-success-mongo")

val mongoProxy = system.actorOf(Props[MongoProxyStub], "cameo-success-redis")

val summaryRetrieverActor = system.actorOf(Props(new SummaryRetriever(redisProxy, mongoProxy)), "cameo-retriever1")

implicit val timeout = Timeout(5 seconds)

val future = summaryRetrieverActor ? GetSummary("dataset1")

val result = Await.result(future, timeout.duration).asInstanceOf[DataSetSummary]

println(Some(result.mongo).x)

println(result.redis)

system.shutdown()

}

Application Config:

akka.loglevel = "DEBUG"

akka.event-handlers = ["akka.event.slf4j.Slf4jEventHandler"]

akka.actor.debug.autoreceive = on

akka.actor.debug.lifecycle = on

akka.actor.debug.receive = on

akka.actor.debug.event-stream = on

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值