Orleans 2.0 官方文档 —— 4.9.4 Grains -> 事件溯源 -> 立即确认与延迟确认

立即确认

对于许多应用程序,我们希望确保事件被立即确认,以便持久化的版本不会落后于内存中的当前版本,并且如果grain失败,我们不会冒失去最新状态的风险。我们可以通过以下规则来保证这一点:

  1. 在grain方法返回之前,使用ConfirmEvents来确认所有RaiseEvent调用。

  2. 在grain方法返回之前,确保完成RaiseConditionalEvent返回的任务。

  3. 避免 [Reentrant][AlwaysInterleave]属性,因此,一次只能处理一个grain调用。

如果我们遵循这些规则,则意味着在激发事件之后,在将事件完成写入存储之前,不会执行任何其他的grain代码。因此,内存中的版本与存储中的版本之间的不一致,就不可能发生。虽然这通常情况下正是我们想要的,但它也有一些潜在的缺点。

潜在的缺点

  • 如果与远程集群或存储连接暂时中断,则grain变得不可用:实际上,grain在等待确认事件时,无法执行任何代码,这可能需要无限期的时间(日志一致性协议保持重试,直到恢复存储连接)。

  • 当处理单个grain实例的大量更新时,一次确认一个会变得非常低效,即吞吐量很低。

延迟确认

为了提高上述情况下的可用性和吞吐量,grain可以选择执行以下一项或两项操作:

  • 允许grain方法在不等待确认的情况下激发事件。

  • 允许重入,所以grain可以继续处理新的调用,即使之前的调用卡在等待确认。

这意味着,在某些事件仍处于确认过程中时,可以执行grain代码。JournaledGrain API有一些特殊的规定,可以让开发人员精确控制如何处理当前“飞行中”的未确认事件。

可以检查以下属性,以找出当前未确认的事件:

IEnumerable<EventType> UnconfirmedEvents { get; }

此外,由于State属性返回的状态,不包括未确认事件的影响,因此有一个替代的属性:

StateType TentativeState { get; }

返回“暂定”状态,通过应用所有未确认的事件,从“State”获得。在所有未经确认的事件得到确认后,暂定状态本质上是对成为下一个可能的确认状态的“最佳猜测”。但是,不能保证它实际上会发生,因为grain可能会失败,或者因为这些事件可能会与其他事件竞争并失败,导致它们被取消(如果它们是有条件的),或者出现在序列中的位置比预期要更晚(如果他们是无条件的)。

并发保证

请注意,即使使用重入或延迟确认,Orleans基于回合制的调度(协作并发)保证始终适用。这意味着即使有多个方法正在进行中,只有一个方法可以活跃执行---所有其他方法都处于等待状态,因此并行线程不会引发任何真正的争用。

特别要注意:

  • 属性StateTentativeStateVersion,和UnconfirmedEvents可以在方法的执行期间发生改变。

  • 但这种改变,只能卡在await时发生。

这些保证基于这样的假设:关于任务和async / await ,用户代码保持在推荐的实践范围内。(特别是,不使用线程池任务,或仅将它们用于不调用grain功能且恰当地await的代码)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值