akka/akka-core

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

Open

#17,522 opened on 2015年5月19日

GitHub で見る
 (12 comments) (0 reactions) (0 assignees)Scala (3,547 forks)batch import
1 - triagedhelp wantednice-to-have (low-prio)t:persistence

Repository metrics

Stars
 (13,277 stars)
PR merge metrics
 (平均マージ 17h 35m) (30d で 11 merged PRs)

説明

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.

コントリビューターガイド