访问、保存和删除 Reliable Actors 状态Access, save, and remove Reliable Actors state

Reliable Actors 是可封装逻辑与状态并稳定维护状态的单线程对象。Reliable Actors are single-threaded objects that can encapsulate both logic and state and maintain state reliably. 每个执行组件实例都有其自身的状态管理器:一种类似于字典的数据结构,能够可靠地存储密钥/值对。Every actor instance has its own state manager: a dictionary-like data structure that reliably stores key/value pairs. 状态管理器是围绕状态提供程序的包装。The state manager is a wrapper around a state provider. 无论使用哪个持久性设置,都可以使用它来存储数据。You can use it to store data regardless of which persistence setting is used.

状态管理器密钥必须为字符串。State manager keys must be strings. 值是泛型的,可以是任何类型(包括自定义类型)。Values are generic and can be any type, including custom types. 存储在状态管理器中的值必须可进行数据约定序列化的,因为根据执行组件的状态持久性设置,它们可能在复制期间通过网络传输到其他节点,并且可能写入磁盘。Values stored in the state manager must be data contract serializable because they might be transmitted over the network to other nodes during replication and might be written to disk, depending on an actor's state persistence setting.

状态管理器公开通用字典方法来管理状态,类似于在可靠字典中找到的项目。The state manager exposes common dictionary methods for managing state, similar to those found in Reliable Dictionary.

有关信息,请参阅管理执行组件状态的最佳做法For information, see best practices in managing actor state.

访问状态Access state

通过状态管理器根据键来访问状态。State is accessed through the state manager by key. 状态管理器方法全都是异步的,因为当执行组件具有持久化状态时,它们可能需要磁盘 I/O。State manager methods are all asynchronous because they might require disk I/O when actors have persisted state. 首次访问时,状态对象将缓存在内存中。Upon first access, state objects are cached in memory. 重复访问操作将从内存中直接访问对象并以同步方式返回,而不造成磁盘 I/O 或异步上下文切换的开销。Repeat access operations access objects directly from memory and return synchronously without incurring disk I/O or asynchronous context-switching overhead. 在以下情况下,,将从缓存中删除状态对象:A state object is removed from the cache in the following cases:

  • 从状态管理器中检索对象之后,执行组件方法将引发未经处理的异常。An actor method throws an unhandled exception after it retrieves an object from the state manager.
  • 执行组件在停用之后或发生故障后将重新激活。An actor is reactivated, either after being deactivated or after failure.
  • 状态提供程序将状态分页到磁盘。The state provider pages state to disk. 此行为取决于状态提供程序实现。This behavior depends on the state provider implementation. Persisted 设置的默认状态提供程序具有此行为。The default state provider for the Persisted setting has this behavior.

如果键的条目不存在,可以使用引发 KeyNotFoundException (C#) 或 NoSuchElementException(Java) 的标准 Get 操作来检索状态:You can retrieve state by using a standard Get operation that throws KeyNotFoundException(C#) or NoSuchElementException(Java) if an entry does not exist for the key:

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
    public MyActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId)
    {
    }

    public Task<int> GetCountAsync()
    {
        return this.StateManager.GetStateAsync<int>("MyState");
    }
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl extends FabricActor implements  MyActor
{
    public MyActorImpl(ActorService actorService, ActorId actorId)
    {
        super(actorService, actorId);
    }

    public CompletableFuture<Integer> getCountAsync()
    {
        return this.stateManager().getStateAsync("MyState");
    }
}

如果键的条目不存在,也可以使用不引发的 TryGet 方法来检索状态:You can also retrieve state by using a TryGet method that does not throw if an entry does not exist for a key:

class MyActor : Actor, IMyActor
{
    public MyActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId)
    {
    }

    public async Task<int> GetCountAsync()
    {
        ConditionalValue<int> result = await this.StateManager.TryGetStateAsync<int>("MyState");
        if (result.HasValue)
        {
            return result.Value;
        }

        return 0;
    }
}
class MyActorImpl extends FabricActor implements  MyActor
{
    public MyActorImpl(ActorService actorService, ActorId actorId)
    {
        super(actorService, actorId);
    }

    public CompletableFuture<Integer> getCountAsync()
    {
        return this.stateManager().<Integer>tryGetStateAsync("MyState").thenApply(result -> {
            if (result.hasValue()) {
                return result.getValue();
            } else {
                return 0;
            });
    }
}

保存状态Save state

状态管理器检索方法将返回对本地内存中对象的引用。The state manager retrieval methods return a reference to an object in local memory. 只是在本地内存中修改此对象并不会永久存储该对象。Modifying this object in local memory alone does not cause it to be saved durably. 从状态管理器检索和修改对象时,必须将它重新插入状态管理器才能永久保存。When an object is retrieved from the state manager and modified, it must be reinserted into the state manager to be saved durably.

可以使用无条件的 Set(相当于 dictionary["key"] = value 语法)来插入状态:You can insert state by using an unconditional Set, which is the equivalent of the dictionary["key"] = value syntax:

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
    public MyActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId)
    {
    }

    public Task SetCountAsync(int value)
    {
        return this.StateManager.SetStateAsync<int>("MyState", value);
    }
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl extends FabricActor implements  MyActor
{
    public MyActorImpl(ActorService actorService, ActorId actorId)
    {
        super(actorService, actorId);
    }

    public CompletableFuture setCountAsync(int value)
    {
        return this.stateManager().setStateAsync("MyState", value);
    }
}

可以使用 Add 方法添加状态。You can add state by using an Add method. 尝试添加已存在的键时,该方法会引发 InvalidOperationException(C#) 或 IllegalStateException(Java)。This method throws InvalidOperationException(C#) or IllegalStateException(Java) when it tries to add a key that already exists.

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
    public MyActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId)
    {
    }

    public Task AddCountAsync(int value)
    {
        return this.StateManager.AddStateAsync<int>("MyState", value);
    }
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl extends FabricActor implements  MyActor
{
    public MyActorImpl(ActorService actorService, ActorId actorId)
    {
        super(actorService, actorId);
    }

    public CompletableFuture addCountAsync(int value)
    {
        return this.stateManager().addOrUpdateStateAsync("MyState", value, (key, old_value) -> old_value + value);
    }
}

还可以使用 TryAdd 方法添加状态。You can also add state by using a TryAdd method. 尝试添加已存在的键时,该方法不会引发。This method does not throw when it tries to add a key that already exists.

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
    public MyActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId)
    {
    }

    public async Task AddCountAsync(int value)
    {
        bool result = await this.StateManager.TryAddStateAsync<int>("MyState", value);

        if (result)
        {
            // Added successfully!
        }
    }
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl extends FabricActor implements  MyActor
{
    public MyActorImpl(ActorService actorService, ActorId actorId)
    {
        super(actorService, actorId);
    }

    public CompletableFuture addCountAsync(int value)
    {
        return this.stateManager().tryAddStateAsync("MyState", value).thenApply((result)->{
            if(result)
            {
                // Added successfully!
            }
        });
    }
}

在执行组件方法结束时,状态管理器会自动保存通过插入或更新操作添加或修改的任何值。At the end of an actor method, the state manager automatically saves any values that have been added or modified by an insert or update operation. 根据所用的设置,“保存”可能包括持久保存到磁盘和复制。A "save" can include persisting to disk and replication, depending on the settings used. 未修改的值不会持久保存或复制。Values that have not been modified are not persisted or replicated. 如果未修改任何值,保存操作不起作用。If no values have been modified, the save operation does nothing. 如果保存失败,将丢弃修改的状态并重新加载原始状态。If saving fails, the modified state is discarded and the original state is reloaded.

也可以通过对执行组件基调用 SaveStateAsync 方法来手动保存状态:You can also save state manually by calling the SaveStateAsync method on the actor base:

async Task IMyActor.SetCountAsync(int count)
{
    await this.StateManager.AddOrUpdateStateAsync("count", count, (key, value) => count > value ? count : value);

    await this.SaveStateAsync();
}
interface MyActor {
    CompletableFuture setCountAsync(int count)
    {
        this.stateManager().addOrUpdateStateAsync("count", count, (key, value) -> count > value ? count : value).thenApply();

        this.stateManager().saveStateAsync().thenApply();
    }
}

删除状态Remove state

可以通过调用 Remove 方法,从执行组件的状态管理器中永久删除状态。You can remove state permanently from an actor's state manager by calling the Remove method. 尝试删除不存在的键时,该方法会引发 KeyNotFoundException(C#) 或 NoSuchElementException(Java)。This method throws KeyNotFoundException(C#) or NoSuchElementException(Java) when it tries to remove a key that doesn't exist.

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
    public MyActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId)
    {
    }

    public Task RemoveCountAsync()
    {
        return this.StateManager.RemoveStateAsync("MyState");
    }
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl extends FabricActor implements  MyActor
{
    public MyActorImpl(ActorService actorService, ActorId actorId)
    {
        super(actorService, actorId);
    }

    public CompletableFuture removeCountAsync()
    {
        return this.stateManager().removeStateAsync("MyState");
    }
}

还可以使用 TryRemove 方法永久删除状态。You can also remove state permanently by using the TryRemove method. 尝试删除不存在的键时,该方法不会引发。This method does not throw when it tries to remove a key that does not exist.

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
    public MyActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId)
    {
    }

    public async Task RemoveCountAsync()
    {
        bool result = await this.StateManager.TryRemoveStateAsync("MyState");

        if (result)
        {
            // State removed!
        }
    }
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl extends FabricActor implements  MyActor
{
    public MyActorImpl(ActorService actorService, ActorId actorId)
    {
        super(actorService, actorId);
    }

    public CompletableFuture removeCountAsync()
    {
        return this.stateManager().tryRemoveStateAsync("MyState").thenApply((result)->{
            if(result)
            {
                // State removed!
            }
        });
    }
}

后续步骤Next steps

存储在 Reliable Actors 中的状态必须进行序列化,然后才能将其写入到磁盘并进行复制以实现高可用性。State that's stored in Reliable Actors must be serialized before its written to disk and replicated for high availability. 详细了解执行组件类型序列化Learn more about Actor type serialization.

接下来,详细了解执行组件诊断和性能监视Next, learn more about Actor diagnostics and performance monitoring.