Udostępnij za pośrednictwem


Uzyskiwanie dostępu, zapisywanie i usuwanie stanu elementów Reliable Actors

Reliable Actors to jednowątkowy obiekt, który może hermetyzować zarówno logikę, jak i stan, i niezawodnie utrzymywać stan. Każde wystąpienie aktora ma własnego menedżera stanu: struktura danych przypominająca słownik, która niezawodnie przechowuje pary klucz/wartość. Menedżer stanu jest otoką dostawcy stanu. Można go użyć do przechowywania danych niezależnie od tego, które ustawienie trwałości jest używane.

Klucze menedżera stanu muszą być ciągami. Wartości są ogólne i mogą być dowolnym typem, w tym typami niestandardowymi. Wartości przechowywane w menedżerze stanu muszą być serializacji kontraktu danych, ponieważ mogą być przesyłane przez sieć do innych węzłów podczas replikacji i mogą być zapisywane na dysku, w zależności od ustawienia trwałości stanu aktora.

Menedżer stanu uwidacznia typowe metody słownika do zarządzania stanem, podobnie jak te znalezione w reliable dictionary.

Aby uzyskać informacje, zobacz najlepsze rozwiązania dotyczące zarządzania stanem aktora.

Stan dostępu

Dostęp do stanu jest uzyskiwany za pośrednictwem menedżera stanu za pomocą klucza. Metody menedżera stanu są asynchroniczne, ponieważ mogą wymagać we/wy dysku, gdy aktorzy mają stan utrwalone. Po pierwszym dostępie obiekty stanu są buforowane w pamięci. Powtarzaj operacje dostępu do obiektów bezpośrednio z pamięci i zwracają synchronicznie bez ponoszenia obciążenia we/wy dysku lub asynchronicznego przełączania kontekstu. Obiekt stanu jest usuwany z pamięci podręcznej w następujących przypadkach:

  • Metoda aktora zgłasza nieobsługiwany wyjątek po pobraniu obiektu z menedżera stanu.
  • Aktor jest ponownie uaktywniany po dezaktywacji lub po awarii.
  • Stan strony dostawcy stanu na dysku. To zachowanie zależy od implementacji dostawcy stanu. Domyślny dostawca stanu dla Persisted tego ustawienia ma to zachowanie.

Stan można pobrać przy użyciu standardowej operacji Get , która zgłasza błąd KeyNotFoundException(C#) lub NoSuchElementException(Java), jeśli wpis nie istnieje dla klucza:

[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");
    }
}

Stan można również pobrać przy użyciu metody TryGet , która nie zgłasza, jeśli wpis nie istnieje dla klucza:

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;
            });
    }
}

Zapisz stan

Metody pobierania menedżera stanu zwracają odwołanie do obiektu w pamięci lokalnej. Modyfikowanie tego obiektu w samej pamięci lokalnej nie powoduje jego trwałego zapisania. Po pobraniu obiektu z menedżera stanu i zmodyfikowaniu go należy ponownie zapisać w menedżerze stanu, aby można je było trwale zapisać.

Stan można wstawić przy użyciu zestawu bezwarunkowego, który jest odpowiednikiem dictionary["key"] = value składni:

[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);
    }
}

Stan można dodać przy użyciu metody Add . Ta metoda zgłasza błąd InvalidOperationException(C#) lub IllegalStateException(Java) podczas próby dodania klucza, który już istnieje.

[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);
    }
}

Stan można również dodać przy użyciu metody TryAdd . Ta metoda nie zgłasza błędu podczas próby dodania klucza, który już istnieje.

[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 końcu metody aktora menedżer stanu automatycznie zapisuje wszystkie wartości, które zostały dodane lub zmodyfikowane przez operację wstawiania lub aktualizacji. "Zapisz" może obejmować utrwalanie dysku i replikacji, w zależności od użytych ustawień. Wartości, które nie zostały zmodyfikowane, nie są utrwalane ani replikowane. Jeśli żadne wartości nie zostały zmodyfikowane, operacja zapisywania nic nie robi. Jeśli zapisywanie nie powiedzie się, zmodyfikowany stan zostanie odrzucony, a oryginalny stan zostanie ponownie załadowany.

Stan można również zapisać ręcznie, wywołując metodę SaveStateAsync w bazie aktora:

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();
    }
}

Usuń stan

Stan można trwale usunąć z menedżera stanu aktora, wywołując metodę Remove . Ta metoda zgłasza błąd KeyNotFoundException(C#) lub NoSuchElementException(Java) podczas próby usunięcia klucza, który nie istnieje.

[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");
    }
}

Stan można również usunąć trwale przy użyciu metody TryRemove . Ta metoda nie zgłasza błędu podczas próby usunięcia klucza, który nie istnieje.

[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!
            }
        });
    }
}

Następne kroki

Stan przechowywany w elementach Reliable Actors musi być serializowany, zanim zostanie zapisany na dysku i zreplikowany w celu zapewnienia wysokiej dostępności. Dowiedz się więcej o serializacji typu aktora.

Następnie dowiedz się więcej na temat diagnostyki aktora i monitorowania wydajności.