首页 文章

轻量级的普通期货或Akka

提问于
浏览
0

有一些用例如下 .

1) createUser API调用是通过前端进行的 . 一旦此调用成功,意味着数据成功保存到db,将成功返回到前端 . API Contract 在前端和后端之间结束 .

2)现在后端需要生成并触发 CreateUser 事件,该事件将用户创建到第三方应用程序中(为了示例,我们可以说它成功或失败 . 但是所有对此 CreateUser 事件的调用都必须记录,因为它的失败或成功用于审计和补救(如果失败)的目的 .

First approach 是我们为这些异步事件设计基于 Future 的异步API(应用程序的其余部分大量使用 Futuresasync ),将传入事件和结果成功/失败记录到db中 .

Second approach 是我们使用Akka并且有这些事件的个体演员(例如 CreateUser 就是一个例子) . 这可能看起来像

class CreateUserActor extends Actor {

def receive = {
case CreateUserEvent(user, role) =>
  val originalSender = sender
  val res = Future {
    blocking {
    //persist CreateUserEvent to db

      SomeService.createUser(user, role)
    }
  }
  res onComplete {
    case Success(u) => //persist success to db
    case Failure(e) => //persist failure to db
  }

}

Third approach 使用Akka Persistence,因此可以通过事件源日记功能实现事件的持久性 . 然而事件的第二个持续性依赖于持续事件的Akka持久性,持续成功/失败事件的第二个要求仍然是手动的,现在必须再保留一个存储(持久的日记等)所以不确定我们是否购买了很多这里?

第二种方法需要为两种情况(传入事件和事件结果)编写持久代码 .

第一种方法可能看起来不太有希望 .

虽然听起来可能听起来像我并不打算创建一个可能听起来像“基于意见”的问题,但试图在其提到的方法或其他任何可能适合的方面提供正面的建议 .

仅供参考:此特定应用程序是在播放服务器上运行的播放应用程序,因此使用Actors不是问题 .

1 回答

  • 2

    由于这是一个Play应用程序,您可以使用Akka事件流来发布事件,而无需引用后端工作者actor .

    例如,在 actors/Subscriber.scala 中包含以下内容:

    package actors
    
    import akka.actor.Actor
    import model._
    
    class Subscriber extends Actor {
      context.system.eventStream.subscribe(self, classOf[DomainEvent])
    
      def receive = {
        case event: DomainEvent =>
        println("Received DomainEvent: " + event)
      }
    }
    

    ......在 model/events.scala 中有类似的东西:

    package model
    
    trait DomainEvent
    
    case class TestEvent(message: String) extends DomainEvent
    

    ...你的控制器可以像这样发布一个TestEvent:

    object Application extends Controller {
      import akka.actor.Props
      import play.libs.Akka
    
      Akka.system.actorOf(Props(classOf[actors.Subscriber]))  // Create the backend actor
    
      def index = Action {
        Akka.system.eventStream.publish(model.TestEvent("message"))  // publish an event
        Ok(views.html.index("Hi!"))
      }
    }
    

相关问题