Erlang OTP: Programmering af distribuerede og fejltolerante systemer · Lektion

GenStatem til tilstandshåndtering

Bliv fortrolig med GenStatem til opbygning af robuste finite state machines, håndtering af komplekse tilstandsovergange og effektiv behandling af events.

Lektion 1 af 411 trin

GenStatem til tilstandshåndtering er en gratis Erlang OTP: Programmering af distribuerede og fejltolerante systemer-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Erlang OTP: Programmering af distribuerede og fejltolerante systemer, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Erlang OTP: Programmering af distribuerede og fejltolerante systemer-kurset indeholder 4 lektioner i alt.

Mød GenStatem

Velkommen til GenStatem! Det er et OTP-adfærdsmønster i Erlang, der bruges til at opbygge endelige tilstandsmaskiner (FSM'er). Hvis en komponent i dit system skal opføre sig forskelligt afhængigt af dens aktuelle tilstand, er GenStatem et godt værktøj.

Tænk på det som et specialiseret værktøj til håndtering af kompleks tilstandslogik, der giver mere eksplicit kontrol over tilstandsovergange end en almindelig GenServer.

Grundlæggende om FSM'er

En endelig tilstandsmaskine (FSM) er en matematisk beregningsmodel, der beskriver et systems adfærd. Den kan kun være i én tilstand ad gangen.

  • Tilstande: Forskellige betingelser, som et system kan være i (f.eks. "tændt", "slukket", "inaktiv", "aktiv").
  • Hændelser: Input eller forekomster, der udløser en ændring af tilstanden (f.eks. "knap_trykket", "timeout").
  • Overgange: Regler, der definerer, hvordan en hændelse i en bestemt tilstand medfører et skift til en ny tilstand.

Grundlæggende om GenStatem-moduler

Ligesom andre OTP-adfærdsmønstre kræver GenStatem et callback-modul. Dette modul implementerer bestemte funktioner, der definerer FSM'ens adfærd.

Den mest grundlæggende funktion er init/1, som opretter den indledende tilstand og data for din FSM. 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, [], []).

Tilstande og StateData

I GenStatem er en tilstand typisk en atom (f.eks. :on, :off). StateData er et vilkårligt Erlang-term, der indeholder de interne oplysninger, som er knyttet til den aktuelle tilstand, på samme måde som en GenServers tilstand.

Når du skifter tilstand, angiver du både den nye tilstandsatom og de nye tilstandsdata. Det gør det muligt at føre kontekst og oplysninger videre mellem forskellige tilstande i din FSM.

Reaktion på hændelser

GenStatem bruger callback-funktioner til at reagere på hændelser. Ved asynkrone hændelser (f.eks. gen_statem:cast/2) bruges callbacken handle_event/4.

Funktionssignaturen er State(EventType, EventContent, StateData), hvor State er den aktuelle tilstandsatom, og EventType angiver meddelelsens type (f.eks. :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}.

Ændring af tilstande

Returneringsværdien fra dine funktioner, der håndterer hændelser, bestemmer FSM'ens næste handling. Hvis du vil ændre tilstand, returnerer du en tupel: {:next_state, NewState, NewStateData}.

  • NewState: Atomen, der repræsenterer den næste tilstand.
  • NewStateData: De opdaterede tilstandsdata, der føres videre til den nye tilstand.

Hvis du vil blive i den aktuelle tilstand, kan du returnere {:keep_state, NewStateData} eller {:keep_state_and_data}, hvis dataene ikke ændres.

Synkrone og asynkrone hændelser

GenStatem håndterer forskellige typer hændelser:

  • handle_call/4: Til synkrone kald (gen_statem:call/3). Den kaldende part venter på et svar.
  • handle_event/4: Til asynkrone cast-kald (gen_statem:cast/2) og interne meddelelser (gen_statem:info/2 eller procesmeddelelser). Den kaldende part venter ikke.
  • handle_info/4: En specialiseret version af handle_event til procesmeddelelser, der ikke stammer fra gen_statem:cast eller gen_statem:call. Den bruges ofte mindre i tilstanden state_functions.

Vi fokuserer på handle_call og handle_event i vores eksempel.

Eksempel: Lyskontakt

Lad os bygge en klassisk FSM: en lyskontakt! Den har to tilstande: off og on.

Vi sender en toggle-hændelse for at ændre dens tilstand. Vi tilføjer også en måde at kontrollere dens aktuelle status på.

Kode til lyskontakt

Her er hele Erlang-modulet til vores lyskontakt. Kør det, og prøv at interagere med det!

-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-udfordring

Forestil dig et GenStatem-modul, der repræsenterer en dør med tilstandene :closed og :open. Det modtager hændelserne :open_door og :close_door.

Hvis døren er :closed og modtager :open_door, skifter den til :open. Hvis den er :open og modtager :close_door, skifter den til :closed.

Hvad er den korrekte returværdi fra tilstandsfunktionen closed/4, når den modtager en :open_door-hændelse via gen_statem:cast/2?

GenStatem-opsummering

Flot arbejde med at mestre GenStatem!

Du har lært, at GenStatem er ideel til implementering af finittilstandsmaskiner, så du kan håndtere kompleks logik, der afhænger af tilstanden. De vigtigste pointer er:

  • FSM'er har tilstande, hændelser og overgange.
  • GenStatem bruger tilbagekaldsmoduler og tilstandsfunktioner (f.eks. off/4, on/4).
  • Du skifter mellem tilstande ved hjælp af {:next_state, NewState, NewStateData}.
  • Hændelser kan være asynkrone (cast, håndteret af handle_event/4) eller synkrone (call, håndteret af handle_call/4).

Denne effektive adfærd er en grundsten i opbygningen af robuste og forudsigelige systemer i Erlang.

Gratis at komme i gang

Lær Erlang med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
12
Lektioner
48

Ofte stillede spørgsmål

Er lektionen “GenStatem til tilstandshåndtering” gratis?

Ja — alle 3 lektioner i læringssporet Erlang OTP: Programmering af distribuerede og fejltolerante systemer, inklusive “GenStatem til tilstandshåndtering”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Erlang OTP: Programmering af distribuerede og fejltolerante systemer-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “GenStatem til tilstandshåndtering”?

Bliv fortrolig med GenStatem til opbygning af robuste finite state machines, håndtering af komplekse tilstandsovergange og effektiv behandling af events. Du øver dig i Erlang OTP: Programmering af distribuerede og fejltolerante systemer med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Erlang OTP: Programmering af distribuerede og fejltolerante systemer?

Der kræves ingen tidligere erfaring. Erlang OTP: Programmering af distribuerede og fejltolerante systemer på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.

Hvor lang tid tager lektionen “GenStatem til tilstandshåndtering”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Erlang OTP: Programmering af distribuerede og fejltolerante systemer-lektion?

Ja. Alle Erlang OTP: Programmering af distribuerede og fejltolerante systemer-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. GenStatem til tilstandshåndtering
  2. GenEvent til eventhåndtering
  3. Tilpassede OTP-behaviors
  4. Hot code swapping og live upgrades
← Tilbage til Erlang OTP: Programmering af distribuerede og fejltolerante systemer