akka/akka-core

[idea] Asynchronous validation andThen persist(event) in PersistentActor

Open

#17,522 创建于 2015年5月19日

在 GitHub 查看
 (12 评论) (0 反应) (0 负责人)Scala (3,547 fork)batch import
1 - triagedhelp wantednice-to-have (low-prio)t:persistence

仓库指标

Star
 (13,277 star)
PR 合并指标
 (平均合并 17小时 35分钟) (30 天内合并 11 个 PR)

描述

Inside an PersistentActor, sometimes users may need to ask some other actor to perform validation of a message, before it knows if it can persist it or not. Maybe there's a shared "geo-location address checker actor" or something like that.

Currently it is possible to emulate such asynchronous validation by something among the lines of:

trait ValidationResult { def withHandler(fn: Any => Unit): ValidationResult = this }
final case class Invalid(event: Any) extends ValidationResult
final case class Validated(event: Any, handler: Any => Unit) extends ValidationResult { 
  def def withHandler(handler: Any => Unit) = copy(fn = handler)
}

def receive = {
  case Validated(event, handler) => persist(validated)(handler)
  case Invalid(event) => log.warning("Invalid event! {}", event)
  case event => 
    val handler = (e: Any) => () // some handler anything you like here
    (validator ? PleaseValidate(event))
      .mapTo[Validated]
      .map(_.withHandler(handler)) // set the handler (so we did not have to send it to the validator)
      .pipeTo(self) // send the validation response to self
}

However perhaps it would be possible to provide a method / trait that would help facilitate this pattern. Of course, the problem becomes ordering and we would have to think about if we provide two versions (one with stashing, one without) like persist and persistAsync or if we should leave this to users to implement.

This is a loose/fuzzy idea yet comes from a discussion with users who needed this kind of thing.

贡献者指南