Erlang OTP: programmering av distribuerte og feiltolerante systemer · leksjon

GenStatem for tilstandshåndtering

Bli fortrolig med GenStatem for å bygge robuste endelige tilstandsmaskiner, håndtere komplekse tilstandsoverganger og behandle hendelser effektivt.

Leksjon 1 av 411 trinn

GenStatem for tilstandshåndtering er en gratis leksjon i Erlang OTP: programmering av distribuerte og feiltolerante systemer på CoddyKit. Dette er leksjon 1 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Erlang OTP: programmering av distribuerte og feiltolerante systemer, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Erlang OTP: programmering av distribuerte og feiltolerante systemer inneholder totalt 4 leksjoner.

Møt GenStatem

Velkommen til GenStatem! Dette er en OTP-atferd i Erlang som brukes til å bygge finite state machines (FSM-er). Hvis en systemkomponent må oppføre seg forskjellig basert på den nåværende tilstanden, er GenStatem et godt verktøy.

Se på det som et spesialisert verktøy for å håndtere kompleks tilstandslogikk, med mer eksplisitt kontroll over tilstandsoverganger enn en vanlig GenServer.

Grunnleggende om FSM-er

En finite state machine (FSM) er en matematisk beregningsmodell som beskriver hvordan et system oppfører seg. Den kan bare være i én tilstand om gangen.

  • Tilstander: Ulike situasjoner et system kan være i (for eksempel «on», «off», «idle», «active»).
  • Hendelser: Inndata eller forekomster som utløser en endring av tilstand (for eksempel «button_press», «timeout»).
  • Overganger: Regler som definerer hvordan en hendelse i en bestemt tilstand fører til en ny tilstand.

Grunnleggende om GenStatem-modulen

I likhet med andre OTP-atferder krever GenStatem en callback-modul. Denne modulen implementerer bestemte funksjoner som definerer FSM-ens virkemåte.

Den mest grunnleggende funksjonen er init/1, som setter opp den opprinnelige tilstanden og dataene for FSM-en. Den returnerer {:ok, InitialState, InitialStateData}.

-module(my_fsm).
-behaviour(gen_statem).

-export([start_link/0]).
-export([init/1]).
-export([callback_mode/0]).

% Minimal init for a GenStatem
init(_Args) ->
    io:format("FSM initializing...~n"),
    InitialState = off, % Our first state
    InitialStateData = [], % Any data we want to carry
    {:ok, InitialState, InitialStateData}.

% Defines how events are handled (state-name based)
callback_mode() ->
    state_functions.

start_link() ->
    gen_statem:start_link({local, ?MODULE}, ?MODULE, [], []).

Tilstander og StateData

I GenStatem er en tilstand vanligvis et atom (for eksempel :on, :off). StateData er et hvilket som helst Erlang-term som inneholder den interne informasjonen som er knyttet til den nåværende tilstanden, på samme måte som tilstanden i en GenServer.

Når du går over til en annen tilstand, angir du både det nye tilstands-atomet og de nye tilstandsdataene. Dermed kan du ta med deg kontekst og informasjon mellom de ulike tilstandene i FSM-en.

Reagere på hendelser

GenStatem bruker callback-funksjoner til å reagere på hendelser. For asynkrone hendelser (som gen_statem:cast/2) brukes callback-funksjonen handle_event/4.

Funksjonssignaturen er State(EventType, EventContent, StateData), der State er det nåværende tilstands-atomet, og EventType angir meldingstypen (for eksempel :cast, :info).

% Example for 'off' state
off(cast, toggle, StateData) ->
    io:format("Switching to ON from OFF~n"),
    {:next_state, on, StateData}; % Transition to 'on' state

off(info, _Msg, StateData) ->
    io:format("Received info in OFF state~n"),
    {:next_state, off, StateData}.

Endre tilstander

Returverdien fra funksjonene som håndterer hendelser, bestemmer FSM-ens neste handling. For å endre tilstand returnerer du en tuppel: {:next_state, NewState, NewStateData}.

  • NewState: Atomet som representerer den neste tilstanden.
  • NewStateData: De oppdaterte tilstandsdataene som skal tas med inn i den nye tilstanden.

Hvis du vil bli i den nåværende tilstanden, kan du returnere {:keep_state, NewStateData}, eller {:keep_state_and_data} hvis dataene ikke endres.

Synkrone og asynkrone hendelser

GenStatem håndterer ulike typer hendelser:

  • handle_call/4: For synkrone kall (gen_statem:call/3). Den som kaller, venter på et svar.
  • handle_event/4: For asynkrone cast-kall (gen_statem:cast/2) og interne meldinger (gen_statem:info/2 eller prosessmeldinger). Den som kaller, venter ikke.
  • handle_info/4: En spesialisert variant av handle_event for prosessmeldinger som ikke kommer fra gen_statem:cast eller gen_statem:call. Den brukes ofte mindre i modusen state_functions.

Vi fokuserer på handle_call og handle_event i eksempelet vårt.

Eksempel: lysbryter

La oss bygge en klassisk FSM: en lysbryter! Den skal ha to tilstander: off og on.

Vi sender en toggle-hendelse for å endre tilstanden. Vi legger også til en måte å kontrollere den nåværende statusen på.

Kode for lysbryter

Her er hele Erlang-modulen for lysbryteren vår. Kjør den og prøv å samhandle med den!

-module(light_switch).
-behaviour(gen_statem).

-export([start_link/0, toggle/0, status/0]).
-export([init/1, callback_mode/0]).
-export([off/4, on/4]). % Export state functions

% -- Public API --
start_link() ->
    gen_statem:start_link({local, ?MODULE}, ?MODULE, [], []).

toggle() ->
    gen_statem:cast(?MODULE, toggle).

status() ->
    gen_statem:call(?MODULE, status).

% -- GenStatem Callbacks --
init(_Args) ->
    io:format("Light switch initializing to OFF~n"),
    {:ok, off, []}. % Initial state 'off', no specific data

callback_mode() ->
    state_functions.

% -- State 'off' callbacks --
off(cast, toggle, StateData) ->
    io:format("Switching from OFF to ON~n"),
    {:next_state, on, StateData};
off(call, status, From, StateData) ->
    gen_statem:reply(From, off),
    {:keep_state, StateData};
off(EventType, EventContent, StateData) ->
    io:format("OFF state received unhandled event: ~p, ~p~n", [EventType, EventContent]),
    {:keep_state, StateData}.

% -- State 'on' callbacks --
on(cast, toggle, StateData) ->
    io:format("Switching from ON to OFF~n"),
    {:next_state, off, StateData};
on(call, status, From, StateData) ->
    gen_statem:reply(From, on),
    {:keep_state, StateData};
on(EventType, EventContent, StateData) ->
    io:format("ON state received unhandled event: ~p, ~p~n", [EventType, EventContent]),
    {:keep_state, StateData}.

% --- How to run this code in Erlang shell: ---
% c(light_switch).
% light_switch:start_link().
% light_switch:status(). % Should be 'off'
% light_switch:toggle().
% light_switch:status(). % Should be 'on'
% light_switch:toggle().
% light_switch:status(). % Should be 'off'

GenStatem-utfordring

Se for deg en GenStatem-modul som representerer en dør med tilstandene :closed og :open. Den mottar hendelsene :open_door og :close_door.

Hvis døren er :closed og mottar :open_door, går den over til :open. Hvis den er :open og mottar :close_door, går den over til :closed.

Hva er den riktige returverdien fra tilstandsfunksjonen closed/4 når den mottar en :open_door-hendelse via gen_statem:cast/2?

GenStatem-oppsummering

Godt jobbet med å mestre GenStatem!

Du har lært at GenStatem egner seg svært godt til å implementere finite state machines, slik at du kan håndtere kompleks logikk som avhenger av tilstand. Viktige punkter:

  • FSM-er har tilstander, hendelser og overganger.
  • GenStatem bruker callback-moduler og tilstandsfunksjoner (for eksempel off/4 og on/4).
  • Du går mellom tilstander ved å bruke {:next_state, NewState, NewStateData}.
  • Hendelser kan være asynkrone (cast, håndtert av handle_event/4) eller synkrone (call, håndtert av handle_call/4).

Denne kraftige atferden er en grunnpilar for å bygge robuste og forutsigbare systemer i Erlang.

Gratis å komme i gang

Lær deg Erlang med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
12
Leksjoner
48

Ofte stilte spørsmål

Er leksjonen «GenStatem for tilstandshåndtering» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Erlang OTP: programmering av distribuerte og feiltolerante systemer, inkludert «GenStatem for tilstandshåndtering», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Erlang OTP: programmering av distribuerte og feiltolerante systemer inneholder totalt 4 leksjoner.

Hva lærer jeg i «GenStatem for tilstandshåndtering»?

Bli fortrolig med GenStatem for å bygge robuste endelige tilstandsmaskiner, håndtere komplekse tilstandsoverganger og behandle hendelser effektivt. Du øver på Erlang OTP: programmering av distribuerte og feiltolerante systemer med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Erlang OTP: programmering av distribuerte og feiltolerante systemer?

Ingen tidligere erfaring er nødvendig. Erlang OTP: programmering av distribuerte og feiltolerante systemer på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 1 av 4.

Hvor lang tid tar leksjonen «GenStatem for tilstandshåndtering»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Erlang OTP: programmering av distribuerte og feiltolerante systemer-leksjonen?

Ja. Alle Erlang OTP: programmering av distribuerte og feiltolerante systemer-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. GenStatem for tilstandshåndtering
  2. GenEvent for hendelseshåndtering
  3. Egendefinerte OTP-atferder
  4. Hot code swapping og live upgrades
← Tilbake til Erlang OTP: programmering av distribuerte og feiltolerante systemer