GenStage и конвейеры с обратным давлением
Создавайте конвейеры обработки данных, управляемые спросом, с помощью GenStage: потребители регулируют поток посредством обратного давления, предотвращая перегрузку распределённых систем.
«GenStage и конвейеры с обратным давлением» — бесплатный урок Elixir & Phoenix: Scalable Backend Development на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Elixir & Phoenix: Scalable Backend Development, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Elixir & Phoenix: Scalable Backend Development содержит 4 уроков всего.
Части этого урока еще не переведены и отображаются на английском.
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.
Часто задаваемые вопросы
Урок «GenStage и конвейеры с обратным давлением» бесплатный?
Да — полный текст урока «GenStage и конвейеры с обратным давлением» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Elixir & Phoenix: Scalable Backend Development, подпишись на CoddyKit PRO. Курс Elixir & Phoenix: Scalable Backend Development содержит 4 уроков всего.
Чему я научусь в уроке «GenStage и конвейеры с обратным давлением»?
Создавайте конвейеры обработки данных, управляемые спросом, с помощью GenStage: потребители регулируют поток посредством обратного давления, предотвращая перегрузку распределённых систем. Ты практикуешь Elixir & Phoenix: Scalable Backend Development с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Elixir & Phoenix: Scalable Backend Development?
Предыдущий опыт не требуется. Elixir & Phoenix: Scalable Backend Development на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «GenStage и конвейеры с обратным давлением»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Elixir & Phoenix: Scalable Backend Development?
Да. Каждый урок Elixir & Phoenix: Scalable Backend Development включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Распределённый Elixir и кластеризация
- Расширенные стратегии супервизии
- Динамические супервизоры и реестр
- GenStage и конвейеры с обратным давлением