简体   繁体   English

在Akka的执着演员中,创造一个被认为是副作用的儿童演员,还是创造国家?

[英]In Akka's persistent actor, is creating a child actor considered to be a side effect, or the creation of state?

This question isn't as philosophical as the title might suggest. 这个问题并不像标题所暗示的那样具有哲学性。 Consider the following approach to persistence: 考虑以下持久性方法:

Commands to perform Operations come in from various Clients. 执行操作的命令来自各种客户端。 I represent both Operations and Clients as persistent actors. 我将操作和客户都表示为持久的角色。 The Client's state is the lastOperationId to pass through. 客户端的状态是要通过的lastOperationId。 The Operation's state is pretty much an FSM of the Operation's progress (it's effectively a Saga, as it then needs to reach out to other systems external to the ActorSystem in order to move through it's states). Operation的状态几乎是操作进度的FSM(它实际上是一个Saga,因为它需要接触到ActorSystem外部的其他系统才能通过它的状态)。

A Reception actor receives the operation command, which contains the client id and operation id. 接收者接收操作命令,其包含客户端ID和操作ID。 The Reception actor creates or retrieves the Client actor and forwards it the command. Reception actor创建或检索Client actor并将其转发给命令。 The Client actor reads and validates the operation command, persists it, creates an OperationReceived event, updates its own state with the this operation id. Client actor读取并验证操作命令,持久化它,创建OperationReceived事件,使用此操作id更新其自己的状态。 Now it needs to create a new Operation actor to manage the new long-running operation. 现在需要创建一个新的Operation actor来管理新的长期运行操作。 But here is where I get lost and all the nice examples in the documentation and on the various blogs don't help. 但这里是我迷路的地方,文档和各种博客中的所有好例子都无济于事。 Most commentators say that a PersistentActor converts commands to events, and then updates their state. 大多数评论员说PersistentActor将命令转换为事件,然后更新其状态。 They may also have side effects as long as they are not invoked during replay. 只要在重放期间不调用它们,它们也可能具有副作用。 So I have two areas of confusion: 所以我有两个困惑的领域:

  1. Is the creation of an Operation actor in this context equivalent to creating state, or performing a side effect? 在此上下文中创建操作actor是否等同于创建状态或执行副作用? It doesn't seem like a side effect, but at the same time it's not changing its own state, but causing a state change in a new child. 它似乎不是副作用,但同时它不会改变自己的状态,而是导致新孩子的状态改变。
  2. Am I supposed to construct a Command to send to the new Operation actor or will I simply forward it the OperationReceived event? 我是否应该构建一个Command来发送给新的Operation actor,或者我只是将它转发给OperationReceived事件?

If I go with my assumption that creating a child actor is not a side effect, it means I must also create the child when replaying. 如果我假设创建一个儿童演员不是副作用,那就意味着我还必须在重播时创建一个孩子。 This in turn would cause the state of the child to be recovered. 这反过来会导致孩子的状态得以恢复。

I hope the underlying question is clear. 我希望潜在的问题是明确的。 I feel it's a general question, but the best way I can formulate it is by giving a specific example. 我觉得这是一个普遍的问题,但我能够制定它的最好方法是给出一个具体的例子。

Edit : On reflection, I think that the creation of one persistent actor from another is an act of creating state, albeit outsourced. 编辑 :经过反思,我认为从另一个创建一个持久的演员是一种创造国家的行为,虽然是外包的。 That means that the event that triggers the creation will trigger that creation on a subsequent replay (which will lead to the retrieval of the child's own persisted state). 这意味着触发创建的事件将在后续重放时触发该创建(这将导致检索子项自己的持久状态)。 This makes me think that passing the event (rather than a wrapping command) might be the cleanest thing to do as the same event can be applied to update the state in both parent and child. 这使我认为传递事件(而不是包装命令)可能是最干净的事情,因为可以应用相同的事件来更新父和子中的状态。 There should be no need to persist the event as it comes into the child - it has already been persisted in the parent and will replay. 当事件进入孩子时,应该没有必要坚持这个事件 - 它已经存在于父母身上并将重播。

On reflection, I think that the creation of one persistent actor from another is an act of creating state, albeit outsourced. 经过反思,我认为从另一个角色创造一个持久的演员是一种创造国家的行为,虽然是外包的。 That means that the event that triggers the creation will trigger that same creation on a subsequent replay. 这意味着触发创建的事件将在后续重播时触发相同的创建。 This makes me think that passing the event (rather than a wrapping command) might be the cleanest thing to do as the same event can be applied to update the state in both parent and child. 这使我认为传递事件(而不是包装命令)可能是最干净的事情,因为可以应用相同的事件来更新父和子中的状态。 There should be no need to persist the event as it comes into the child - it has already been persisted in the parent and will replay. 当事件进入孩子时,应该没有必要坚持这个事件 - 它已经存在于父母身上并将重播。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM