---
metadata:
  - name: generator
    content: Diplodoc Platform v5.63.3
alternate:
  - https://ytsaurus.tech/docs/en/flow/concepts/companion-resources.md
  - https://ytsaurus.tech/docs/ru/flow/concepts/companion-resources.md
  - href: https://ytsaurus.tech/docs/ru/flow/concepts/companion-resources.md
    type: text/markdown
    title: Markdown version
  - href: https://ytsaurus.tech/docs/ru/llms.txt?revision=181542d8c2d9f36be925894a517db8203cafae65
    rel: describedby
---
> **Documentation Index:** Fetch the complete configuration index at https://ytsaurus.tech/docs/ru/llms.txt?revision=181542d8c2d9f36be925894a517db8203cafae65

# Ресурсы компаньона: краткий дизайн

Ресурс компаньона — это тяжёлый объект, которым управляет Flow, но который живёт в
процессе-компаньоне и доступен пользовательским process function. Например, это может быть
распакованный словарь, модель или пул соединений. Ресурс общий для всего процесса-компаньона,
а не для отдельного джоба, поэтому он не должен хранить изменяемое состояние джоба и обязан
поддерживать параллельное использование.

## Компоненты

- Контроллер ресурса определяет желаемую ревизию и публикует её в Flow.
- `TCompanionResource` на воркере является прокси: готовит ревизию, управляет жизненным циклом
  и отправляет команды в компаньон.
- `TResourceStore` в C++-компаньоне хранит ресурсы по `resource_id`. Хранилище принадлежит
  процессу и переживает создание и удаление джобов.
- Process function получает только ресурсы, перечисленные в `required_resource_ids`, с учётом
  алиасов и транзитивных зависимостей.

## Доставка и ссылки

Воркер вызывает RPC `ResourceExecute(resource_id, command, argument)`. Команда задаётся enum и
имеет два значения: `init` и `unload`. Результат содержит отдельный статус команды ресурса и
структурированную ошибку `TError`.

Основной путь использует идемпотентный `init`. В аргумент входят статическая и динамическая
спеки, подготовленная ревизия, идентификатор и поколение инкарнации, поколение конфигурации и
точные ссылки на зависимости. Зависимости инициализируются раньше зависимого ресурса. В `TJobInfo`
передаются те же точные ссылки: `resource_id`, `incarnation_id`,
`configuration_generation` и необязательный алиас. Перед запуском пользовательского кода
компаньон проверяет каждую ссылку и выдаёт process function ссылки только на совпавшие
экземпляры.

## Реконфигурация и восстановление

- Новая целевая ревизия сначала асинхронно готовится на воркере через
  `PrepareResourceRevision`; неуспешный результат не публикуется в компаньон.
- Успешная подготовка увеличивает поколение конфигурации и запускает сходящийся `init`.
- Компаньон публикует новое поколение только после того, как ресурс применил целевую ревизию:
  `Reconfigure` по контракту может лишь передать цель асинхронному переключению. Пока
  `GetRevisionState` сообщает отстающую применённую ревизию, `init` возвращает временный
  `resource_not_initialized`, а повторы сходятся без пересоздания экземпляра.
- Монотонное поколение инкарнации не позволяет запоздалой команде оживить старый экземпляр или
  удалить новый.
- Воркер периодически повторяет `init`, а каждый компьютейшен доставляет требуемые ресурсы по
  своему каналу. Это восстанавливает состояние после перезапуска процесса-компаньона.
- Если `ProcessBatch` возвращает `RESOURCE_NOT_INITIALIZED`, воркер повторно инициализирует граф
  ресурсов, обновляет ссылки и сведения о джобе и повторяет запрос с ограниченным числом попыток.
- `unload` выполняется по возможности. Уже работающие джобы удерживают ссылки на старый объект,
  но новые джобы его больше не получают.

Полная серверная реализация сейчас есть у C++-компаньона. Java, Go и Python пока возвращают из
`ResourceExecute` статус `Unsupported`.
