在某项目里,有个 actor 需要做一些持久化的操作,这些操作耗时比较久,理应使用异步的代码来写,但是需求又强调每次只能做一个持久化操作,后来的请求应该等待。一个显然的做法是阻塞式的写,这样就能比较简单的实现顺序花操作。

代码写完以后,我觉得在 actor 中 block 不够完美,就想其他的解决方案。实际上,借助 akka actor 的一些函数,可以实现在不阻塞的情况下实现顺序执行请求的功能的。这种办法的核心是使用 become, unbecome 函数:actor 设置两种状态 free 和 busy,当 free 的时,处理消息,当 busy 时,暂时将消息存储起来,处理消息后,给 actor 返回 done 指令,actor 的状态重新返回到 free,准备处理下一个请求。具体的实现又有很多细节可以考虑,比如当 busy 时到来的请求存储到哪里,是 stash 起来还是在 actor 内部维护一个 queue。请求的处理逻辑是写在 actor 内部,还是借鉴 cameo 模式,再创建一个 actor。

网上已有一种实现,我看了下,觉得应该没有问题。只不过 actor 内部维护了一个 queue,这可能会造成 actor 死亡后重启数据丢失的情况。更好的办法应该是 cameo 模式创建新的 actor 来处理可能出现异常(危险)的工作,其次是把 actor 的 mailbox 当做那个 queue,不要自己维护,按照 doc 缩写,actor 重启后,mailbox 的消息不会丢失。

package actors

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global import akka.actor.{ Actor, ActorRef } import play.api.libs.concurrent.Akka
import play.api.Logger
import play.api.Play.current trait SequentialActor {
this: Actor => import SequentialActor._ // Actor defines type Receive as PartialFunction[Any, Unit]
type ReceiveAsync = PartialFunction[Any, Future[_]] private val queue = scala.collection.mutable.Queue[Job]()
private def enqueue(job: Job): Unit = queue enqueue job
private def dequeue: Option[Job] = if (queue.isEmpty) None else Some(queue.dequeue) private var _senderAsync: ActorRef = _
def senderAsync = _senderAsync def receive: Receive = {
case msg =>
context become busy
process(Job(msg, sender))
} def busy: Receive = {
case Done =>
dequeue match {
case None => context.unbecome
case Some(job) => process(job)
}
case msg =>
enqueue(Job(msg, sender))
} def process(job: Job) {
_senderAsync = job.sender
(receiveAsync orElse fallback)(job.msg).onComplete { _ => self ! Done }
} def receiveAsync: ReceiveAsync def fallback: ReceiveAsync = {
case msg =>
Logger.error(s"Unhandled message: $msg")
Future.successful{ () }
} }
object SequentialActor {
case object Done
case class Job(msg: Any, sender: ActorRef)
}

  

顺序执行到来的消息 actor的更多相关文章

  1. 关于MQ的几件小事(五)如何保证消息按顺序执行

    1.为什么要保证顺序 消息队列中的若干消息如果是对同一个数据进行操作,这些操作具有前后的关系,必须要按前后的顺序执行,否则就会造成数据异常.举例: 比如通过mysql binlog进行两个数据库的数据 ...

  2. .NET中按预定顺序执行任务

    更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月1日. 一.说明 在.NET中线程可以定义按先后顺序进行执行,适合部分有先后次序的业务逻辑.Task也可以按照预定义的先后顺序执行 ...

  3. js的并行加载以及顺序执行

    重新温习了下这段内容,发现各个浏览器的兼容性真的是搞大了头,处理起来很是麻烦. 现在现总结下并行加载多个js的方法: 1,对于动态createElement('script')的方式,对所有浏览器都是 ...

  4. 【原创】cs+html+js+css模式(七): 顺序执行与并发执行问题,IIS7及其以上版本的抛错问题解决

          在进行开发的过程中,针对于这种模式,我们继承的IRequiresSessionState,这种对于我们的同一个IIS的执行中是顺序执行即一个ajax请求处理完成后,才能执行下一个ajax, ...

  5. testng xml中按顺序执行java类

    如红字部份,将安顺序执行4个类 <?xml version="1.0" encoding="UTF-8"?><suite name=" ...

  6. js的并行加载与顺序执行

    javaScript文件(下面简称脚本文件)需要被HTML文件引用才能在浏览器中运行.在HTML文件中可以通过不同的方式来引用脚本文件,我们需要关注的是,这些方式的具体实现和这些方式可能会带来的性能问 ...

  7. gulp顺序执行任务

    gulp的任务的执行是异步的. 所以,当我写完一系列的任务,准备一股脑地执行. # gulp.task('prod', ['clean', 'compass', 'image', 'style', ' ...

  8. testng.xml顺序执行多个case配置

    testng.xml顺序执行多个case配置 项目结构如图:

  9. 多命令顺序执行、管道符 ; && || |

    多命令顺序执行:

随机推荐

  1. C#函数式编程之部分应用

    何谓函数式编程 相信大家在实际的开发中,很多情况下完成一个功能都需要借助多个类,那么我们这里的基本单元就是类.而函数式编程则更加细化,致使我们解决一个功能的基本单元是函数,而不是类,每个功能都是由多个 ...

  2. 基于Criminisi算法的栅格影像数据敏感地物隐藏

    栅格影像数据敏感地物伪装是指通过计算机智能识别与计算,将影像数据中的敏感地物进行识别与提取,将敏感地物智能替换成公共地物,如草地.森林.湖泊.公园等.但目前该技术并不成熟,同时栅格影像数据敏感地物伪装 ...

  3. Linux:Linux 重要人物

    1.Ken Thompson:C 语言之父和 UNIX 之父 2.Dennis Ritchie:C 语言之父和 UNIX 之父 3.Stallman:著名黑客,GNU 创始人,开发了 Emacs.gc ...

  4. [BTS] The adapter "SQL" raised an error message. Details "The Messaging Engine is shutting down. ".

    Get a warning in event log. Log Name:      ApplicationSource:        BizTalk ServerDate:          3/ ...

  5. atitit.二进制数据无损转字符串网络传输

    atitit.二进制数据无损转字符串网络传输 1. gbk的网络传输问题,为什么gbk不能使用来传输二进制数据 1 2. base64 2 3. iso-8859-1  (推荐) 2 4. utf-8 ...

  6. sqlserver自定义函数的创建与调用

    sqlserver中有系统提供的函数,像avg.sum.getdate()等,用户还可以自定义函数. 用户自定义的函数包括:标量函数和表值函数,其中标量函数和系统函数的用法一样,表值函数根据主体的定义 ...

  7. $.ajax()方法解析

    $.ajax()方法,在web网站开发中常用到,作为一种用于创建快速动态网页的技术(异步JavaScript和XML).通过在后台与服务器进行少量数据交换,AJAX可以使网页实现异步更新.这意味着可以 ...

  8. Android系统分区理解及分区目录细解

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  9. [原创]Java性能优化权威指南读书思维导图

    [原创]Java性能优化权威指南读书思维导图 书名:Java性能优化权威指南 原书名:Java performance 作者: (美)Charlie Hunt    Binu John 译者: 柳飞 ...

  10. iOS7隐藏状态栏 statusBar

    转:http://blog.csdn.net/dqjyong/article/details/17896145 评:通过这点变化,可以看出苹果倾向于使用delegate取代全局变量. IOS7中,不仅 ...