GenStage i potoki ze sterowaniem przepływem
Buduj sterowane zapotrzebowaniem potoki danych za pomocą GenStage, w których konsumenci kontrolują przepływ przez mechanizm backpressure, zapobiegając przeciążeniom w systemach rozproszonych.
GenStage i potoki ze sterowaniem przepływem to bezpłatna lekcja Elixir & Phoenix: Scalable Backend Development na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Elixir & Phoenix: Scalable Backend Development, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Elixir & Phoenix: Scalable Backend Development zawiera 4 lekcji w sumie.
Części tej lekcji nie zostały jeszcze przetłumaczone i są wyświetlane po angielsku.
The Overload Problem
When a fast producer feeds a slow consumer, messages pile up and memory explodes. Backpressure solves this: consumers signal how much work they can handle, and producers send only that much.
What is GenStage?
GenStage is an Elixir behaviour for building staged, demand-driven pipelines. Data flows from producers to consumers, with optional producer-consumer stages in between.
The Three Stage Types
Every GenStage process plays one role:
- Producer: emits events on demand
- ProducerConsumer: receives, transforms, and re-emits
- Consumer: receives and processes events
Defining a Producer
A producer implements init/1 and handle_demand/2. It returns events only when consumers ask for them.
defmodule Counter do
use GenStage
def init(start), do: {:producer, start}
def handle_demand(demand, state) do
events = Enum.to_list(state..(state + demand - 1))
{:noreply, events, state + demand}
end
endDefining a Consumer
A consumer implements handle_events/3. It returns no events itself, only acknowledging the demand it processed.
defmodule Printer do
use GenStage
def init(_), do: {:consumer, :ok}
def handle_events(events, _from, state) do
for e <- events, do: IO.inspect(e)
{:noreply, [], state}
end
endSubscribing Stages
Connect a consumer to a producer with GenStage.sync_subscribe/2. The max_demand option caps how many events flow at once.
{:ok, prod} = GenStage.start_link(Counter, 0)
{:ok, cons} = GenStage.start_link(Printer, :ok)
GenStage.sync_subscribe(cons, to: prod, max_demand: 10)How Backpressure Works
The consumer requests up to max_demand events. The producer can never send more than was requested, so a slow consumer naturally throttles a fast producer. No buffering blowup.
Producer-Consumer Stages
A middle stage transforms data. It implements handle_events/3 but returns transformed events for the next stage.
def handle_events(events, _from, state) do
doubled = Enum.map(events, &(&1 * 2))
{:noreply, doubled, state}
endConsumerSupervisor
For concurrent processing, ConsumerSupervisor spawns a short-lived child process per event, bounded by demand. This parallelizes work while keeping backpressure intact.
Flow for Parallel Pipelines
The Flow library builds on GenStage to offer map/reduce-style parallel data processing with partitioning — ideal for crunching large collections across cores.
File.stream!("big.csv")
|> Flow.from_enumerable()
|> Flow.map(&parse_line/1)
|> Flow.partition()
|> Enum.to_list()When to Reach for GenStage
Use GenStage when you have:
- A rate mismatch between data source and processing
- Streaming data that must not overwhelm memory
- Multi-stage transformation pipelines
Quick Check
Test your GenStage knowledge.
Recap
You learned demand-driven pipelines:
- GenStage has producers, producer-consumers, and consumers
- Consumers request bounded demand for backpressure
- Subscribe stages with
sync_subscribeandmax_demand ConsumerSupervisorparallelizes per-event workFlowbuilds parallel map/reduce pipelines on top
Backpressure keeps distributed systems stable under load.
Często zadawane pytania
Czy lekcja „GenStage i potoki ze sterowaniem przepływem” jest bezpłatna?
Tak — pełny tekst „GenStage i potoki ze sterowaniem przepływem” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Elixir & Phoenix: Scalable Backend Development, przejdź na CoddyKit PRO. Kurs Elixir & Phoenix: Scalable Backend Development zawiera 4 lekcji w sumie.
Co nauczysz się w „GenStage i potoki ze sterowaniem przepływem”?
Buduj sterowane zapotrzebowaniem potoki danych za pomocą GenStage, w których konsumenci kontrolują przepływ przez mechanizm backpressure, zapobiegając przeciążeniom w systemach rozproszonych. Ćwiczysz Elixir & Phoenix: Scalable Backend Development z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Elixir & Phoenix: Scalable Backend Development?
Nie wymagamy żadnego doświadczenia. Elixir & Phoenix: Scalable Backend Development w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „GenStage i potoki ze sterowaniem przepływem”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Elixir & Phoenix: Scalable Backend Development?
Tak. Każda lekcja Elixir & Phoenix: Scalable Backend Development zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Rozproszony Elixir i klastrowanie
- Zaawansowane strategie nadzoru
- Dynamiczne superwizory i rejestr
- GenStage i potoki ze sterowaniem przepływem