持久化

Grain可以具有多个与之关联的已命名的持久数据对象(named persistent data objects)。在激活Grain时,状态会从存储中加载,便于在请求时使用。Grain的持久化使用可扩展插件模型,可以使用任何数据库的存储提供器(storage provider)。该持久化模型设计简明,无意涵盖所有数据访问模式。Grain也可以直接访问数据库,无需使用Grain持久化模型。
image.png
如上图所示,UserGrain实体有两个状态:ProfileCart。这两种状态分别存在不同的存储系统中。

目标

  1. 一个Grain可以具有多个已命名的持久化数据对象;
  2. 可以有多个存储提供器,每个存储提供器配置可以不同,也可以由不同的存储系统支持;
  3. 社区可以开发和发布存储提供器;
  4. 存储提供器对它们如何在持久化后台存储中保存Grain状态,具有完全的控制权。

结论:Orleans没有提供全面的ORM存储解决方案,但允许通过定制存储提供器来支持具体的ORM需求。

Orleans的Grain存储提供器可以从NuGet中找到。其中,由官方团队维护的包有:

API

Grain使用IPersistentState<TState>接口与其持久化状态进行交互,其中TState是可序列化的状态类型:

  1. public interface IPersistentState<TState> where TState : new()
  2. {
  3. TState State { get; set; }
  4. string Etag { get; }
  5. Task ClearStateAsync();
  6. Task WriteStateAsync();
  7. Task ReadStateAsync();
  8. }

实现了IPersistentState<TState>的实例可以通过构造器注入到Grain中。这些参数应标记上[``PersistentState(stateName, storageName)``]特性,其中:

  • stateName为被注入的状态的名字;
  • storageName为相应的存储提供器的名字。

以下的示例代码给上面图中UserGrain的构造器注入了两个state:

  1. public class UserGrain : Grain, IUserGrain
  2. {
  3. private readonly IPersistentState<ProfileState> _profile;
  4. private readonly IPersistentState<CartState> _cart;
  5. public UserGrain(
  6. [PersistentState("profile", "profileStore")] IPersistentState<ProfileState> profile,
  7. [PersistentState("cart", "cartStore")] IPersistentState<CartState> cart,
  8. )
  9. {
  10. _profile = profile;
  11. _cart = cart;
  12. }
  13. }

不同的Grain类型可以使用不同配置的存储提供器,即便存储提供器类型相同:两个不同的Azure Table Storage存储提供器,可以连接的是不同的Azure Storage账户。

读取状态

写入状态

清理状态

开始吧

持久化操作失效模式

读取操作失效模式

写入操作失效模式

推荐实现

使用Grain将存储添加给Grain

创建存储提供器(storage provider)

存储提供器语法

数据映射

注册存储提供器