---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.6
alternate:
  - https://ytsaurus.tech/docs/en/flow/go/examples/async_request.md
  - https://ytsaurus.tech/docs/ru/flow/go/examples/async_request.md
---
> **Documentation Index:** Fetch the complete configuration index at https://ytsaurus.tech/docs/ru/llms.txt

<!-- source: ru/_includes/flow/go/examples/async_request.md -->
# Async Request в YTsaurus Flow (Go)

Пример [пайплайна](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#pipeline), реализующего асинхронный поход во внешний сервис: один [компьютейшен](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#stream-and-computation) превращает события в запросы и накапливает ответы во внешнем [стейте](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#state), другой обслуживает запросы без стейта. Go-реализация того же сценария, что и [C++ пример](https://ytsaurus.tech/docs/ru/flow/cpp/examples/async_request.md).

[Исходный код](https://github.com/ytsaurus/ytsaurus/tree/main/yt/yt/flow/examples/go/async_request)

## Структура {#structure}

Компаньон обслуживает два компьютейшена, `injector` остаётся нативным сорсом из [спеки](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#spec-and-dynamic-spec):

1. **`state`** (`stateKeeper`) — stateful-компьютейшен, сгруппированный по `key`, который:
   - принимает события из стрима `event` и порождает запрос в стрим `request` со случайным `request_id`;
   - принимает ответы из стрима `response` и складывает суммарную длину (`total_length`) во внешний стейт `/state`.

2. **`processor`** (`requestProcessor`) — stateless-компьютейшен, сгруппированный по `request_id`: принимает запросы из стрима `request` и сразу отвечает длиной строки запроса в стрим `response`.

Цикл `event → request → response → state` замыкается между двумя компьютейшенами. Событие отвечается запросом, а не сразу результатом, поэтому обслуживающая сторона никогда не задерживает обработку: ответ приходит позже, отдельным [сообщением](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#message), и только тогда стейт ключа сдвигается.

## `main.go` {#main-go}

Точка входа: создание пайплайна и регистрация обоих компьютейшенов.

[Исходный код: `main.go`](https://github.com/ytsaurus/ytsaurus/tree/main/yt/yt/flow/examples/go/async_request/main.go)

{% code '/yt/yt/flow/examples/go/async_request/main.go' lang='go' lines='[BEGIN main]-[END main]' %}

## `state_keeper.go` {#state-keeper-go}

Маршрутизация входных стримов (`event` / `response`) и работа с внешним стейтом.

{% code '/yt/yt/flow/examples/go/async_request/state_keeper.go' lang='go' lines='[BEGIN state_keeper]-[END state_keeper]' %}

## `request_processor.go` {#request-processor-go}

Stateless-обработчик запросов: вычисляет длину строки запроса и возвращает ответ.

{% code '/yt/yt/flow/examples/go/async_request/request_processor.go' lang='go' lines='[BEGIN request_processor]-[END request_processor]' %}

## Ключевые паттерны {#key-patterns}

- **Маршрутизация по `msg.StreamID`**: `switch` по идентификатору входного стрима позволяет одному компьютейшену обрабатывать несколько входов с разной логикой. Неизвестный стрим — ошибка, а не молчаливое игнорирование.
- **Случайный `request_id`**: `rand.Uint64()` связывает запрос с ответом. Запрос несёт ключ исходного события, поэтому ответ, партиционированный по `request_id`, возвращается к тому стейту, которому принадлежит поход.
- **Внешний стейт** через `flow.OpenExternalState(rt, "/state", msg)`: строка преобразуется в `totalLengthState` через `ConvertTo`, изменяется как структура и сохраняется через `ConvertFrom`.
- **Stateless-компьютейшен**: `requestProcessor` не использует стейт и сгруппирован по `request_id`, а не по ключу события, поэтому запросы одного ключа расходятся по всем [партициям](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#partition) и масштабируются независимо.
- **Зависимость стримов**: `streams_dependency` в спеке объявляет, что `request` порождается из `event` — воркер учитывает это при продвижении [вотермарков](https://ytsaurus.tech/docs/ru/flow/concepts/watermarks.md).
<!-- endsource: ru/_includes/flow/go/examples/async_request.md -->

<!-- source: ru/_includes/flow/go/examples/async_request_also.md -->
## См. также

- [Быстрый старт (Go)](https://ytsaurus.tech/docs/ru/flow/go/getting-started.md)
- [Computation (Go)](https://ytsaurus.tech/docs/ru/flow/go/computation.md)
- [External State (Go)](https://ytsaurus.tech/docs/ru/flow/go/external-state.md)
- [Аналогичный пример на C++](https://ytsaurus.tech/docs/ru/flow/cpp/examples/async_request.md)
- [Аналогичный пример на Java](https://ytsaurus.tech/docs/ru/flow/java/examples/async_request.md)
<!-- endsource: ru/_includes/flow/go/examples/async_request_also.md -->
