# Сборка тасклетов

Тасклет (tasklet) — самодостаточная единица исполнения полезной работы, пригодная к переиспользованию.
Интерфейс (входы и выходы) каждого тасклета описывается с помощью protobuf-сообщения,
а логика обработки данных может быть реализована на различных языках программирования.

Соответственно, при написании тасклетов используется два специфичных макроса сборки: `TASKLET` и `TASKLET_REG`.

Больше информации о тасклетах ищите в [основной документации данной библиотеки](https://wiki.yandex-team.ru/sandbox/tasklets/).
Полноценные же примеры тасклетов [можно найти в репозитории](https://a.yandex-team.ru/arc/trunk/arcadia/tasklet/examples).

{% note warning %}

Тасклеты развиваются как мультиязычная технология и в данной документации есть примеры для C++.
Однако, C++ сейчас используется в качестве тестового неосновного языка.
Из-за этого его функциональность сильно ограничена по сравнению с питоном.
Поэтому рекомендуемым языком для разработки тасклетов пока остаётся Python 3.

{% endnote %}

## TASKLET
```
TASKLET()
```
Данный макрос включает генерацию кода, необходимого для работы тасклета, описанного в protobuf-библиотеке в текущей сборочной цели.
Из этого следует, что макрос имеет смысл только в рамках [PROTO_LIBRARY](/ya-make/manual/proto/).

Пример файла `ya.make`:
```
PROTO_LIBRARY()

OWNER(g:tasklet)

TASKLET()

SRCS(
    my_tasklet.proto
)

END()
```


## TASKLET_REG
```
TASKLET_REG(Name, Language, Implementation, Includes...)
```
Данный макрос предназначен для регистрации класса, имплементирующего тасклет, в реестре тасклетов.
Регистрацию следует осуществлять прямо в библиотеке (`[PY3_]LIBRARY`) с кодом класса.

Параметры:
- `Name` – уникальное имя, по которому имплементация тасклета может быть найдена (при запуске из консоли, например) внутри бинарника, включающего тасклет.
Из-за требования уникальности возможно возникновение конфликтов при включении нескольких тасклетов с одинаковыми именами в одну программу, что приведёт к ошибкам сборки.
Для избежания этого имена тасклетов должны быть осмысленными и не слишком короткими.

- `Language` – язык программирования, на котором тасклет реализован. Возможные значения: `py` (Python 3) и`cpp` (C++).

- `Implementation` – путь до регистрируемого класса. Формат пути зависит то языка программирования:
  - `path.to.python.package:ImplementationClassName` для питона,
  - `NNamespace::TImplementation` для C++.

- `Includes` – пути до header-файлов, которые должны быть подключены к генерируемому коду.
Данный параметр используется только для тасклетов на C++.
В нём надо указать путь до хэдера, в котором объявлен класс тасклета.
Формат: `path/to/library/header_name.h`.

{% cut "Пример ya.make для тасклета на Python" %}
```
PY3_LIBRARY()

OWNER(g:owner-of-library)

PY_SRCS(
    __init__.py
)

TASKLET_REG(MyTasklet py path.to.python.package:MyTaskletClass)

PEERDIR(
    path/to/tasklet/proto
)

END()
```
{% endcut %}

{% cut "Пример ya.make для тасклета на C++" %}
```
LIBRARY()

USE_PYTHON3()  # it is required because C++ binary uses python 2 by default

OWNER(g:owner-of-library)

SRCS()  # Empty here because all code could be in header

TASKLET_REG(
    MyTasklet cpp NNamespace::TMyTaskletClass path/to/library/header_name.h
)

PEERDIR(
    path/to/tasklet/proto
)

END()
```
{% endcut %}




## Бинарник тасклета {#binary}
Тасклеты описываются в библиотеках. Для создания же бинарника, исполняющего тасклеты, используется python-программа с CLI, реализованном в `tasklet/cli`.

`ya.make` минимального тасклета выглядит так:

```
PY3_PROGRAM()

OWNER(g:owner-of-program)

PY_MAIN(tasklet.cli.main)

PEERDIR(
    path/to/tasklet/library

    tasklet/cli
)

END()
```


`tasklet.cli.main` определяет хендлер run. Ему можно передать:
имя тасклета для запуска (под которым тасклет был зарегистрирован в `TASKLET_REG`),
инпуты в виде json map и среду исполнения (`local`, `sandbox-tasklet` или `yt`).
Пример запуска:
```bash
$ ya make tasklet/examples/sum && tasklet/examples/sum/sum run SumPy --input '{"num1": 1, "num2": 2}' --local
```

При запуске в Sandbox (`--sandbox-tasklet`) будет создана задача, тип, входные и выходные параметры которой будут сгенерированы на основе протобуфа тасклета.
Больше информации об аргументах запуска собранного бинарника можно получить при помощи вызова с флагом `-h/--help`.

{% note warning %}

Бинарникам тасклетов обязательно требуется server-side исполнение. Как следствие, работают только бинарники, собранные для linux.
Попытка запустить в этом режиме программы, собранные на, например, macOS, приведёт к ошибкам создания задачи.

{% endnote %}
