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.
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/2eller procesmeddelelser). Den kaldende part venter ikke.handle_info/4: En specialiseret version afhandle_eventtil procesmeddelelser, der ikke stammer fragen_statem:castellergen_statem:call. Den bruges ofte mindre i tilstandenstate_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 afhandle_event/4) eller synkrone (call, håndteret afhandle_call/4).
Denne effektive adfærd er en grundsten i opbygningen af robuste og forudsigelige systemer i Erlang.
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
- GenStatem til tilstandshåndtering
- GenEvent til eventhåndtering
- Tilpassede OTP-behaviors
- Hot code swapping og live upgrades