尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Orleans JournaledGrain 状态变更通知:OnStateChanged 与 OnTentativeStateChanged 完整指南

发布时间:2026/9/24 14:44:31

资讯中心
01
ARTICLE

Orleans JournaledGrain 状态变更通知:OnStateChanged 与 OnTentativeStateChanged 完整指南

Orleans JournaledGrain 状态变更通知:OnStateChanged 与 OnTentativeStateChanged 完整指南
后端微服务【免费下载链接】orleansCloud Native application framework for .NET项目地址https://gitcode.com/gh_mirrors/or/orleans点击查看免费下载JournaledGrain日志一致性 Grain是 Orleans 事件溯源Event Sourcing体系的核心抽象。当确认视图confirmed view或暂定视图tentative view发生变化时Orleans 会通过两个受保护回调把变化通知给开发者OnStateChanged与OnTentativeStateChanged。本文以仓库文档 notifications.md 为主体结合 JournaledGrain.cs 与 PrimaryBasedLogViewAdaptor.cs 的源码实现讲解这两个回调的触发时机、源码级调用链、使用边界与编写注意事项。读完本文你将能正确地在事件溯源 Grain 中监听状态变化并规避把回调误当作恰好一次集成事件的常见陷阱。两个回调的分工确认视图与暂定视图JournaledGrainTGrainState, TEventBase内部维护两种视图对应两组属性详见 journaledgrain-basics.md确认视图State仅包含已确认confirmed的事件Version等于已确认事件总数暂定视图TentativeState在确认视图基础上叠加了本地已提交但尚未确认的事件UnconfirmedEvents返回当前未确认后缀。两个回调分别对应这两类视图的变化。文档给出的标准覆写方式如下完整代码见 EventSourcingSnippets.csprotected override void OnStateChanged() { // Inspect State and Version. } protected override void OnTentativeStateChanged() { // Inspect TentativeState and UnconfirmedEvents. }注意JournaledGrain的这两个回调默认实现为空见 JournaledGrain.cs你只覆写关心的那个即可它们都是protected virtual只能由派生 Grain 内部调用外部调用者无法直接触发。OnStateChanged确认版本可能已增加文档明确指出覆写OnStateChanged用于在确认版本可能已经增加之后做出反应。它属于通知型回调不是精确到每次变更都恰好调用一次的强保证。三个典型触发时机从源码调用链看OnStateChanged在以下场景被触发激活时加载了更新的状态。JournaledGrain.OnActivateAsync默认调用LogViewAdaptor.Synchronize()等待从存储加载最新视图见 JournaledGrain.cs加载完成后若确认视图前进便会触发回调本地事件被确认。RaiseEvent/RaiseEvents提交的事件经日志一致性适配器写入主存储后确认版本前进并触发回调见下文源码路径收到协议通知。集群中其他副本写入新事件后会向本副本发送版本通知消息触发一次强制刷新needRefresh从而更新确认视图见 PrimaryBasedLogViewAdaptor.cs 与ProcessNotifications逻辑。重要边界它不是恰好一次的集成事件回调这是本文最需要强调的约束OnStateChanged不是 exactly-once 的集成事件回调。它可能因激活重放、后台确认、协议同步等原因被多次调用调用次数与业务上发生了多少次事件没有一一对应关系。因此不要在这里执行外部副作用发邮件、调第三方 API、写其他系统等除非你的应用自带幂等机制或 outbox发件箱协议。若确实需要可靠的集成语义应当基于事件日志本身设计例如在自定义存储或日志存储之上结合RetrieveConfirmedEvents消费已确认事件段并配合幂等键或 outbox 模式落库。OnTentativeStateChanged暂定视图变化通知OnTentativeStateChanged在暂定视图发生变化时被调用。触发源同样是源码中明确可查的RaiseEvent会立即触发它。JournaledGrain.RaiseEventTEvent内部调用LogViewAdaptor.Submit(event)见 JournaledGrain.csSubmit在把事件放入 pending 队列后立刻调用Host.OnViewChanged(true, false)见 PrimaryBasedLogViewAdaptor.cs其中true表示暂定视图已变化。也就是说只要调用了RaiseEventOnTentativeStateChanged就会在同一回合内被调用确认或同步改变了暂定后缀。当批量写主存储成功、事件从 pending 队列移除时暂定视图随之变化OnViewChanged(false, true)见 PrimaryBasedLogViewAdaptor.cs条件事件失败conflict导致暂定后缀被裁剪。RemoveStaleConditionalUpdates在条件事件因版本冲突失败而移除时也会通知暂定视图变化见 PrimaryBasedLogViewAdaptor.cs清空日志ClearLogAsync后视图被重置同时通知暂定与确认变化见 PrimaryBasedLogViewAdaptor.cs。在OnTentativeStateChanged内你可以检查TentativeState确认 未确认事件叠加后的视图与UnconfirmedEvents未确认后缀用于实现乐观 UI 更新、校验提示等场景。源码级调用链OnViewChanged 如何分发两个回调两个回调的枢纽是ILogViewAdaptorHostTLogView, TLogEntry.OnViewChanged(bool tentative, bool confirmed)JournaledGrain的实现把两个布尔标志直接映射到两个回调void ILogViewAdaptorHostTGrainState, TEventBase.OnViewChanged(bool tentative, bool confirmed) { if (tentative) OnTentativeStateChanged(); if (confirmed) OnStateChanged(); }见 JournaledGrain.cs适配器侧PrimaryBasedLogViewAdaptor在以下位置调用该方法构成完整触发矩阵调用点标志触发场景SubmitInternalSubmit/SubmitRange/TryAppend(true, false)每次提交事件暂定视图立即变化UpdatePrimary批量写成功后(false, true)事件确认确认视图前进NotifyViewChanges读主存储后比较版本按版本差异从存储刷新/收到版本通知后RemoveStaleConditionalUpdates(true, false)条件事件冲突被裁剪ProcessClearLogRequest(true, true)清空日志重置状态值得注意的实现细节暂定视图TentativeState是惰性计算的深拷贝——CalculateTentativeState用Services.DeepCopy复制确认视图后依次重放 pending 事件见 PrimaryBasedLogViewAdaptor.cs因此读取它是安全的且每次回调前后状态对象都是独立的副本。这也提醒我们回调中观察到的是某一时刻的视图快照而非稳定不变的引用。编写回调的硬性约束文档对两个回调提出了一致的编写要求这些要求与 Orleans 的调度模型直接相关在 Orleans 回合式调度turn-based scheduling下执行。回调在 Grain 的调度回合内运行与 Grain 方法共享同一个回合语义可重入reentrant不会让两个回合在不同线程上并行但回合之间存在交错可能回调必须快速返回。OnViewChanged是被日志一致性适配器在 worker 循环中同步调用的见 ILogViewAdaptorHost.cs其中任何耗时操作都会阻塞适配器的后台工作循环进而拖慢确认与同步进度不要假设观察到的状态在后续await之后保持不变。因为回调执行期间可能让出调度其他回合如新的RaiseEvent、协议同步可能已经推进或回退了视图。如果需要跨await使用某个值请先把它捕获到局部变量需要最新状态就重新读取State/TentativeState。这一点与 immediate-vs-delayed-confirmation.md 中状态可跨 await 变化的提醒一脉相承回调里不要直接修改State/TentativeState。状态变更只能通过提交事件驱动RaiseEvent、RaiseEvents、RaiseConditionalEvent等否则会破坏日志一致性协议对视图的掌控。回调与相关 API 的配合使用在实际项目中这两个回调通常与以下 API 协同ConfirmEvents()等待此前提交的所有事件被确认保证强一致线性化读取。确认完成后确认视图前进OnStateChanged会被触发RefreshNow()强制同步最新全局状态并确认已提交事件等价于LogViewAdaptor.Synchronize()。激活时加载新状态、收到远端版本通知后的刷新都走这条路径RaiseConditionalEvent/RaiseConditionalEvents条件提交冲突时返回false。冲突裁剪会触发OnTentativeStateChanged便于你借此刷新 UI 或提示重试RetrieveConfirmedEvents(fromVersion, toVersion)按版本段读取已确认事件。若你需要恰好一次的集成语义推荐基于该 API 自行构建消费游标 幂等/outbox而不是依赖OnStateChangedOnConnectionIssue/OnConnectionIssueResolved连接健康回调用于监控底层存储/复制协议故障见 journaledgrain-diagnostics.md与状态通知回调正交可配合使用。小结OnStateChanged在确认视图可能前进时触发激活加载、本地事件确认、协议通知用于反应已落盘的确定性状态它不是 exactly-once 集成事件回调外部副作用需自行保证幂等或使用 outboxOnTentativeStateChanged在暂定视图变化时触发RaiseEvent立即触发、确认/同步/条件冲突改变暂定后缀用于反应已提交但未确认的乐观视图两者都由ILogViewAdaptorHost.OnViewChanged分发见 JournaledGrain.cs在回合式调度下执行必须快速、无副作用假设、且不直接改写状态。更完整的背景可继续阅读同目录文档event-sourcing 索引、JournaledGrain API 基础、立即确认与延迟确认、日志一致性提供程序 与 多副本实例。赞分享后端微服务【免费下载链接】orleansCloud Native application framework for .NET项目地址https://gitcode.com/gh_mirrors/or/orleans点击查看免费下载相关推荐10 秒把自己变成AI数字人Duix.Avatar本地部署新手完整指南10 秒把自己变成AI数字人Duix.Avatar本地部署新手完整指南 Duix.Avatar 是一款真正开源的 AI 数字人克隆工具只需提交一段 10 秒人工智能AI 应用数字人媒体生成桌面应用LibreHardwareMonitor免费开源的硬件监控工具LibreHardwareMonitor免费开源的硬件监控工具 LibreHardwareMonitor 是一款免费开源的硬件监控工具能实时读取电脑的温度传指标监控如何实现Kazumi插件更新通知桌面通知与状态栏提示完整指南如何实现Kazumi插件更新通知桌面通知与状态栏提示完整指南 Kazumi是一款基于自定义规则的番剧采集APP支持流媒体在线观看和弹幕功能。对于插件驱动型应移动开发桌面应用音视频上一篇Google Java Format作为库使用的终极指南10个简单步骤快速集成下一篇Apache Pinot数据格式支持完全指南Avro、Parquet、JSON等7大格式深度对比创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。