Scala Akka事件采购如何将消息恢复到root?

发布于 2025-02-01 17:56:46 字数 1396 浏览 5 评论 0原文

我目前努力阅读演员的状态,因此在这种情况下,我只想从我的州类中获取历史记录参数 - 例如,在调用端点时将其打印出来。

我已经成功地做到了吗?以前是运营商,但我从未尝试过使用事件采购。

到目前为止,我拥有的代码是:

object MyPersistentBehavior {
  sealed trait Command
  final case class Add(data: String) extends Command
  case object Clear extends Command

  sealed trait Event
  final case class Added(data: String) extends Event
  case object Cleared extends Event

  final case class State(history: List[String] = Nil)

  val commandHandler: (State, Command) => Effect[Event, State] = { (state, command) =>
    command match {
      case Add(data) => Effect.persist(Added(data))
      case Clear     => Effect.persist(Cleared)
    }
  }

  val eventHandler: (State, Event) => State = { (state, event) =>
    event match {
      case Added(data) => state.copy((data :: state.history).take(5))
      case Cleared     => State(Nil)
    }
  }

  def apply(id: String): Behavior[Command] =
    EventSourcedBehavior[Command, Event, State](
      persistenceId = PersistenceId.ofUniqueId(id),
      emptyState = State(Nil),
      commandHandler = commandHandler,
      eventHandler = eventHandler)
}

在我的主要方法中,我想打印状态:

val personActor: ActorSystem[MyPersistentBehavior.Command] = ActorSystem(MyPersistentBehavior("IDDD"), "AHA")
//personActor ? GetState <- something like this

谢谢!

I'm currently struggling with reading the state of my actor, so in this case I just want to get the history parameter from my State class - for example print it when an endpoint is called.

I've successfully managed to do it with ? operator before but I've never tried it with event sourcing.

So far the code I have is this:

object MyPersistentBehavior {
  sealed trait Command
  final case class Add(data: String) extends Command
  case object Clear extends Command

  sealed trait Event
  final case class Added(data: String) extends Event
  case object Cleared extends Event

  final case class State(history: List[String] = Nil)

  val commandHandler: (State, Command) => Effect[Event, State] = { (state, command) =>
    command match {
      case Add(data) => Effect.persist(Added(data))
      case Clear     => Effect.persist(Cleared)
    }
  }

  val eventHandler: (State, Event) => State = { (state, event) =>
    event match {
      case Added(data) => state.copy((data :: state.history).take(5))
      case Cleared     => State(Nil)
    }
  }

  def apply(id: String): Behavior[Command] =
    EventSourcedBehavior[Command, Event, State](
      persistenceId = PersistenceId.ofUniqueId(id),
      emptyState = State(Nil),
      commandHandler = commandHandler,
      eventHandler = eventHandler)
}

In my main method I want to print the state:

val personActor: ActorSystem[MyPersistentBehavior.Command] = ActorSystem(MyPersistentBehavior("IDDD"), "AHA")
//personActor ? GetState <- something like this

Thanks!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暮年 2025-02-08 17:56:46

我没有在Akka中与事件采购合作,而是在文档中快速查看,尽管我有帮助:

case class GetState(replyTo: ActorRef[StatusReply[AddPostDone]]) extends Command

// and in the match for commands:
...
    case GetState(replyTo) =>
      replyTo ! StatusReply.Success(state)

      // or if replyTo was of type ActorRef[State] => 
      replyTo ! state

还有此效果在Akka的事件采购文档中看起来很有趣:

def onCommand(subscriber: ActorRef[State], state: State, command: Command): Effect[Event, State] = {
  command match {
    case Add(data) =>
      Effect.persist(Added(data)).thenRun(newState => subscriber ! newState)
    case Clear =>
      Effect.persist(Cleared).thenRun((newState: State) => subscriber ! newState).thenStop()
  }
}

如您所见,非常易于使用。
您还可以在每次效果之后回复最新状态:

case class AddCommand(number: Int, replyTo: ActorRef[State]) extends Command

// in the command handler
    case add: AddCommand(num, replyTo) => 
      // your logic here
      Event.persist(Added(num)) thenRun { newState => 
        replyTo ! newState
      }

文档中还有很多其他选项,因此我强烈建议您查看: https://doc.akka.io/docs/akka/current/current/typed/persistence.html

I've not worked with event sourcing in akka, but had a quick look in the documentations, and I though this migh help:

case class GetState(replyTo: ActorRef[StatusReply[AddPostDone]]) extends Command

// and in the match for commands:
...
    case GetState(replyTo) =>
      replyTo ! StatusReply.Success(state)

      // or if replyTo was of type ActorRef[State] => 
      replyTo ! state

There is also this Effect which is in akka's event sourcing documentation which looks interesting:

def onCommand(subscriber: ActorRef[State], state: State, command: Command): Effect[Event, State] = {
  command match {
    case Add(data) =>
      Effect.persist(Added(data)).thenRun(newState => subscriber ! newState)
    case Clear =>
      Effect.persist(Cleared).thenRun((newState: State) => subscriber ! newState).thenStop()
  }
}

And is pretty easy to use as you can see.
You can also reply the latest state after each effect:

case class AddCommand(number: Int, replyTo: ActorRef[State]) extends Command

// in the command handler
    case add: AddCommand(num, replyTo) => 
      // your logic here
      Event.persist(Added(num)) thenRun { newState => 
        replyTo ! newState
      }

There are lots of other options in the documentation, so I highly recommend you to take a look: https://doc.akka.io/docs/akka/current/typed/persistence.html

黯然#的苍凉 2025-02-08 17:56:46

好的,如果您需要一个完整的示例,请查看我的博客

您将在博客和GitHub存储库中看到,在那里,您会看到所有演员向呼叫者报告他们的状态的通用“主持”命令。

    def commandHandler(context: ActorContext[CreditSMEvent], cmd: CreditSMEvent, state: State): ReplyEffect[PersistEvent, State] =
      cmd match {
        case onReport(useCaseKey, replyTo) =>
            Effect.reply(replyTo)( ReportResponse(state, java.util.Collections.unmodifiableMap(state.controlObject)))

        case _ =>
            commandHandlerInternal(context, cmd, state)
}

您可以在此在博客中。

希望这对您有帮助。

Ok, if you need a full fledged example, please look to my blog.

You will see in the Blog and in the GitHub Repository, in there you will see a generic a 'onReport' command for all actors to report their State to the caller.

    def commandHandler(context: ActorContext[CreditSMEvent], cmd: CreditSMEvent, state: State): ReplyEffect[PersistEvent, State] =
      cmd match {
        case onReport(useCaseKey, replyTo) =>
            Effect.reply(replyTo)( ReportResponse(state, java.util.Collections.unmodifiableMap(state.controlObject)))

        case _ =>
            commandHandlerInternal(context, cmd, state)
}

You can find it at this point in the blog.

I hope this would help you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文