Přístup, uložení a odebrání stavu Reliable Actors
Reliable Actors jsou objekty s jedním vláknem, které mohou zapouzdřovat logiku i stav a spolehlivě udržovat stav. Každá instance objektu actor má vlastní správce stavu: datovou strukturu podobná slovníku, která spolehlivě ukládá páry klíč/hodnota. Správce stavů je obálka kolem poskytovatele stavu. Můžete ho použít k ukládání dat bez ohledu na to, které nastavení trvalosti se používá.
Klíče správce stavu musí být řetězce. Hodnoty jsou obecné a mohou být libovolným typem, včetně vlastních typů. Hodnoty uložené ve správci stavů musí být serializovatelné, protože se můžou přenášet přes síť do jiných uzlů během replikace a můžou být zapsány na disk v závislosti na nastavení trvalosti stavu objektu actor.
Správce stavů zveřejňuje běžné metody slovníku pro správu stavu, podobně jako ty, které jsou nalezeny ve Reliable Dictionary.
Informace najdete v osvědčených postupech při správě stavu objektu actor.
Stav přístupu
Ke stavu se přistupuje prostřednictvím správce stavu pomocí klíče. Všechny metody správce stavů jsou všechny asynchronní, protože můžou vyžadovat vstupně-výstupní operace disku, pokud mají aktéři trvalý stav. Při prvním přístupu se stavové objekty ukládají do mezipaměti. Zopakujte operace přístupu k objektům přístupu přímo z paměti a vraťte se synchronně bez režijních nákladů na vstupně-výstupní operace disku nebo asynchronního přepínání kontextu. Objekt stavu se odebere z mezipaměti v následujících případech:
- Metoda objektu actor vyvolá neošetřenou výjimku poté, co načte objekt ze správce stavů.
- Objekt actor se znovu aktivuje, a to buď po deaktivaci, nebo po selhání.
- Stav stránky zprostředkovatele stavu na disk. Toto chování závisí na implementaci zprostředkovatele stavu. Toto chování má výchozí zprostředkovatel stavu pro
Persisted
toto nastavení.
Stav můžete načíst pomocí standardní operace Get , která vyvolá KeyNotFoundException
(C#) nebo NoSuchElementException
(Java), pokud pro klíč neexistuje položka:
[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");
}
}
Stav můžete načíst také pomocí metody TryGet , která se nevyvolá, pokud pro klíč neexistuje položka:
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;
});
}
}
Uložit stav
Metody načítání správce stavů vrací odkaz na objekt v místní paměti. Změna tohoto objektu v místní paměti sama nezpůsobí, že by byla uložena trvale. Když se objekt načte ze správce stavu a upraví se, musí se znovu vložit do správce stavu, aby byl uložen trvale.
Stav můžete vložit pomocí nepodmíněné sady, což je ekvivalent dictionary["key"] = value
syntaxe:
[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);
}
}
Stav můžete přidat pomocí metody Add . Tato metoda vyvolá InvalidOperationException
(C#) nebo IllegalStateException
(Java) při pokusu o přidání klíče, který již existuje.
[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);
}
}
Stav můžete přidat také pomocí metody TryAdd . Tato metoda není vyvolá, když se pokusí přidat klíč, který již existuje.
[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!
}
});
}
}
Na konci metody objektu actor správce stavu automaticky uloží všechny hodnoty, které byly přidány nebo upraveny operací vložení nebo aktualizace. Uložení může zahrnovat trvalé uložení na disk a replikaci v závislosti na použitém nastavení. Hodnoty, které nebyly změněny, se neuchovávají ani nereplikují. Pokud nebyly změněny žádné hodnoty, operace uložení nic neuvádí. Pokud se uložení nezdaří, změněný stav se zahodí a původní stav se znovu načte.
Stav můžete také uložit ručně voláním SaveStateAsync
metody na základu objektu actor:
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();
}
}
Odebrat stav
Stav můžete trvale odebrat ze správce stavu objektu actor voláním metody Remove . Tato metoda vyvolá KeyNotFoundException
(C#) nebo NoSuchElementException
(Java) při pokusu o odebrání klíče, který neexistuje.
[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");
}
}
Stav můžete také trvale odebrat pomocí metody TryRemove . Tato metoda není vyvolán při pokusu o odebrání klíče, který neexistuje.
[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!
}
});
}
}
Další kroky
Stav, který je uložený v Reliable Actors, musí být serializován před zápisem na disk a replikován pro zajištění vysoké dostupnosti. Přečtěte si další informace o serializaci typů objektu Actor.
Dále se dozvíte více o diagnostice objektu Actor a monitorování výkonu.