Sdílet prostřednictvím


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.