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.

貢獻者指南