Erlang OTP: Programmering av distribuerade och feltoleranta system · Lektion

GenEvent för händelsehantering

Lär er använda GenEvent för att skapa frikopplade system för händelsehantering där publicerare och prenumeranter kan interagera asynkront.

Lektion 2 av 411 steg

GenEvent för händelsehantering är en gratis lektion i Erlang OTP: Programmering av distribuerade och feltoleranta system på CoddyKit. Detta är lektion 2 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Erlang OTP: Programmering av distribuerade och feltoleranta system, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Erlang OTP: Programmering av distribuerade och feltoleranta system innehåller totalt 4 lektioner.

Varför händelsehantering?

Föreställ er att ni har många delar av er applikation som behöver reagera på något som händer, till exempel när en användare loggar in.

Om varje del anropar alla andra delar direkt blir koden hårt kopplad och svår att ändra. Det är här händelsehantering kommer in!

Introduktion till GenEvent

Erlangs OTP (Open Telecom Platform) tillhandahåller ett kraftfullt beteende, gen_event, för att bygga system för frikopplad händelsehantering.

  • Det implementerar mönstret publisher-subscriber.
  • Utgivare skickar händelser utan att veta vem som tar emot dem.
  • Prenumeranter (så kallade handlers) registrerar sig för att ta emot specifika händelser.
  • Detta främjar lös koppling och gör systemen mer flexibla.

Händelsehanteraren

I centrum av gen_event finns en händelsehanterare. Det är en särskild Erlang-process som fungerar som en central knutpunkt:

  • Den tar emot händelser från utgivare.
  • Den skickar vidare dessa händelser till alla registrerade handlers.

Ni startar en händelsehanterare på samma sätt som andra OTP-beteenden:

-module(event_manager_starter).
-export([start/0]).

start() ->
    % Start a local event manager named 'my_app_events'
    {ok, Pid} = gen_event:start_link({local, my_app_events}),
    io:format("Event manager started with PID: ~p~n", [Pid]),
    ok.

Händelsehanterare: lyssnarna

En händelsehanterare är en Erlang-modul som implementerar beteendet gen_event. Den definierar callback-funktioner som händelsehanteraren anropar när en händelse inträffar.

Tänk på handlers som specialiserade lyssnare, där var och en är intresserad av vissa typer av händelser eller utför en specifik åtgärd när en händelse tas emot.

Skapa en enkel handler

Här är grundstrukturen för en modul med en händelsehanterare. Den viktigaste callback-funktionen är handle_event/2, där ni bearbetar den inkommande händelsen.

-module(my_event_handler).
-behaviour(gen_event).

-export([init/1, handle_event/2, terminate/2]).

init(Args) ->
    io:format("Handler initialized with args: ~p~n", [Args]),
    {ok, []}. % Returns initial state

handle_event(Event, State) ->
    io:format("Handler received event: ~p~n", [Event]),
    % Here you'd process the event
    {ok, State}. % Return new state

terminate(_Args, _State) ->
    io:format("Handler terminating.~n", []),
    ok.

Lägga till handlers i hanteraren

När ni har startat händelsehanteraren och definierat er handler måste ni informera hanteraren om den. Detta görs med gen_event:add_handler/3.

Ni kan lägga till flera handlers i samma hanterare, och var och en tar emot händelserna.

-module(handler_adder).
-export([add_to_manager/1]).

add_to_manager(ManagerName) ->
    % The handler module name (my_event_handler)
    % and any initial arguments for its init/1 function ([] in this case)
    gen_event:add_handler(ManagerName, my_event_handler, []),
    io:format("Handler 'my_event_handler' added to '~p'.~n", [ManagerName]),
    ok.

Meddela hanteraren (publicera händelser)

När handlers har registrerats kan valfri del av applikationen skicka en händelse till hanteraren med gen_event:notify/2. Hanteraren vidarebefordrar sedan händelsen till alla aktiva handlers.

Utgivaren vet inte, och behöver inte bry sig om, hur många handlers som finns eller vad de gör. Det är kraften i frikoppling!

-module(event_publisher).
-export([send_alert/2]).

send_alert(ManagerName, Message) ->
    Event = {alert, Message, os:timestamp()},
    io:format("Publisher sending event: ~p to manager '~p'.~n", [Event, ManagerName]),
    gen_event:notify(ManagerName, Event).

Fullständig GenEvent-demonstration

Nu sätter vi ihop allt! Det här körbara exemplet startar en hanterare, lägger till en enkel handler och skickar sedan några händelser. Se hur handlern reagerar!

-module(gen_event_demo).
-export([start/0]).

% --- Inline Handler Module for Demo ---
% In a real app, this would be a separate .erl file.
my_demo_handler() ->
    % Compile and load a temporary handler module
    code:delete(demo_handler_impl),
    code:purge(demo_handler_impl),
    {ok, _} = compile:forms([
        '-module(demo_handler_impl).',
        '-behaviour(gen_event).',
        '-export([init/1, handle_event/2, terminate/2]).',
        'init(Args) -> {ok, Args}.',
        'handle_event(Event, State) ->',
        '    io:format("*** Handler received: ~p~n", [Event]),',
        '    {ok, State}.',
        'terminate(_Args, _State) -> ok.'
    ], []),
    demo_handler_impl.

% --- Main Application Logic ---
start() ->
    ManagerName = my_system_events,
    HandlerModule = my_demo_handler(),

    io:format("--- Starting GenEvent Demo ---~n"),

    % 1. Start the event manager
    {ok, _ManagerPid} = gen_event:start_link({local, ManagerName}),
    io:format("Manager '~p' started.~n", [ManagerName]),

    % 2. Add the handler to the manager
    gen_event:add_handler(ManagerName, HandlerModule, []), 
    io:format("Handler '~p' added.~n", [HandlerModule]),

    % 3. Publish some events
    io:format("Sending first event...~n"),
    gen_event:notify(ManagerName, {user_logged_in, "Alice"}),
    timer:sleep(100), % Give time for event processing

    io:format("Sending second event...~n"),
    gen_event:notify(ManagerName, {sensor_reading, 25.5}),
    timer:sleep(100),

    io:format("Sending third event...~n"),
    gen_event:notify(ManagerName, {error_alert, "Disk_full"}),
    timer:sleep(100),

    % 4. Stop the manager (optional, for clean exit)
    gen_event:stop(ManagerName),
    io:format("--- GenEvent Demo Finished ---~n"),
    ok.

Avancerad användning av GenEvent

gen_event är mycket flexibelt:

  • Handler-tillstånd: Handlers kan upprätthålla ett eget internt tillstånd som uppdateras med varje händelse.
  • Flera handlers: En enda händelsehanterare kan ha många handlers, där var och en bearbetar händelser oberoende av de andra.
  • Ta bort handlers: Handlers kan tas bort dynamiskt med gen_event:delete_handler/3.
  • Synkrona anrop: Även om gen_event främst är asynkront kan gen_event:call/2 användas för synkrona anrop till handlers (även om detta är mindre vanligt vid ren händelsehantering).

Snabbkontroll av GenEvent

Ni har lärt er om GenEvents centrala delar och hur de samverkar. Nu testar vi era kunskaper!

Repetition: grunderna i GenEvent

Bra jobbat! Ni har lärt er hur gen_event hjälper till att bygga flexibla och frikopplade system:

  • Händelsehanterare: Den centrala knutpunkt som skickar vidare händelser.
  • Händelsehanterare: Moduler som prenumererar på och bearbetar händelser.
  • Utgivare: Skickar händelser till hanteraren med gen_event:notify/2.
  • Frikoppling: Den viktigaste fördelen, eftersom systemets delar kan utvecklas oberoende av varandra.

Härnäst utforskar ni ännu mer avancerade OTP-beteenden!

Gratis att börja

Lär dig Erlang med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
12
Lektioner
48

Vanliga frågor

Är lektionen ”GenEvent för händelsehantering” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Erlang OTP: Programmering av distribuerade och feltoleranta system, inklusive ”GenEvent för händelsehantering”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Erlang OTP: Programmering av distribuerade och feltoleranta system innehåller totalt 4 lektioner.

Vad lär jag mig i ”GenEvent för händelsehantering”?

Lär er använda GenEvent för att skapa frikopplade system för händelsehantering där publicerare och prenumeranter kan interagera asynkront. Ni övar på Erlang OTP: Programmering av distribuerade och feltoleranta system med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Erlang OTP: Programmering av distribuerade och feltoleranta system?

Du behöver inga förkunskaper. Utbildningen i Erlang OTP: Programmering av distribuerade och feltoleranta system på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.

Hur lång tid tar lektionen ”GenEvent för händelsehantering”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Erlang OTP: Programmering av distribuerade och feltoleranta system-lektionen?

Ja. Varje Erlang OTP: Programmering av distribuerade och feltoleranta system-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. GenStatem för tillståndshantering
  2. GenEvent för händelsehantering
  3. Anpassade OTP-behaviors
  4. Hot code swapping och live upgrades
← Tillbaka till Erlang OTP: Programmering av distribuerade och feltoleranta system