Интеграция с Temporal

Wippy интегрируется с Temporal.io для надёжного выполнения workflow, автоматического воспроизведения и долгоживущих процессов, переживающих перезапуски.

Настройка клиента

Тип записи temporal.client определяет подключение к серверу Temporal:

- name: temporal_client
  kind: temporal.client
  address: "localhost:7233"
  namespace: "default"
  lifecycle:
    auto_start: true

Обязательные поля

Поле Описание
address Адрес сервера Temporal (host:port)

Необязательные поля

Поле По умолчанию Описание
namespace "default" Пространство имён Temporal
tq_prefix "" Префикс имени очереди задач для всех операций
connection_timeout "10s" Тайм-аут подключения
keep_alive_time "30s" Интервал keep-alive
keep_alive_timeout "10s" Тайм-аут keep-alive

Аутентификация

Без аутентификации

- name: temporal_client
  kind: temporal.client
  address: "localhost:7233"
  auth:
    type: none

API Key (Temporal Cloud)

API-ключ можно указать несколькими способами:

# Прямое значение
- name: temporal_client
  kind: temporal.client
  address: "your-namespace.tmprl.cloud:7233"
  namespace: "your-namespace"
  auth:
    type: api_key
    api_key: "your-api-key"

# Из переменной окружения
- name: temporal_client
  kind: temporal.client
  address: "your-namespace.tmprl.cloud:7233"
  namespace: "your-namespace"
  auth:
    type: api_key
    api_key: ${env:TEMPORAL_API_KEY}

# Из файла
- name: temporal_client
  kind: temporal.client
  address: "your-namespace.tmprl.cloud:7233"
  namespace: "your-namespace"
  auth:
    type: api_key
    api_key_file: "/etc/secrets/temporal-api-key"

Поля аутентификации и учётных данных разрешают плейсхолдеры ${env:NAME} через реестр окружения при декодировании. Устаревшие директивы api_key_env / key_pem_env разрешаются так же, но не рекомендуются; предпочитайте api_key: ${env:NAME} / key_pem: ${env:NAME}.

mTLS

- name: temporal_client
  kind: temporal.client
  address: "temporal.example.com:7233"
  namespace: "production"
  auth:
    type: mtls
    cert_file: "/path/to/client.pem"
    key_file: "/path/to/client.key"
  tls:
    enabled: true
    ca_file: "/path/to/ca.pem"

Сертификат и ключ также можно передать как PEM-строки или из переменных окружения:

auth:
  type: mtls
  cert_pem: |
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----    
  key_pem: ${env:TEMPORAL_CLIENT_KEY}

Настройка TLS

tls:
  enabled: true
  ca_file: "/path/to/ca.pem"
  server_name: "temporal.example.com"    # Переопределение имени сервера для проверки
  insecure_skip_verify: false            # Пропуск проверки (только для разработки)

Проверка состояния

health_check:
  enabled: true
  interval: "30s"

Передача контекста безопасности

Wippy передаёт вызывающего актора и область в workflow и activity через подписанный заголовок Temporal. Подпись — HMAC-SHA256 с ключом, который хранит запись клиента:

- name: temporal_client
  kind: temporal.client
  address: "localhost:7233"
  security_hmac_key: ${env:TEMPORAL_SECURITY_KEY}
  security_hmac_previous_keys:
    - ${env:TEMPORAL_SECURITY_KEY_PREVIOUS}
Поле Описание
security_hmac_key Ключ подписи в base64; после декодирования должен быть не короче 32 байт
security_hmac_previous_keys Ключи в base64, всё ещё принимаемые при проверке, для ротации

Оба поля записываются в YAML в base64, поскольку это байтовые поля. Ключ короче 32 декодированных байт отклоняется при валидации конфигурации, как и объявление security_hmac_previous_keys без security_hmac_key. Новые заголовки всегда подписываются ключом security_hmac_key; при проверке перебирается каждый перечисленный прежний ключ, поэтому ротация выглядит так: добавьте новый ключ как security_hmac_key, переместите старый в security_hmac_previous_keys, затем удалите его, когда ни одно выполняющееся исполнение его больше не несёт.

Запуск workflow под актором или областью требует ключа. Если у вызывающей стороны есть контекст безопасности, а у клиента нет ключа подписи, заголовок невозможно подписать и запуск завершается неудачей. Клиент без ключа может запускать workflow только из контекста, в котором нет ни актора, ни области.

Ключи воркер получает из записи клиента, на которую ссылается, поэтому подпись и проверку он наследует из client:, ничего не настраивая сам. См. Workflow и Activity.

Настройка воркера

Тип записи temporal.worker определяет воркер, выполняющий workflow и activity:

- name: worker
  kind: temporal.worker
  client: app:temporal_client
  task_queue: "my-app-queue"
  lifecycle:
    auto_start: true
    depends_on:
      - app:temporal_client

Обязательные поля

Поле Описание
client Ссылка на запись temporal.client
task_queue Имя очереди задач

Параметры воркера

Тонкая настройка поведения воркера:

- name: worker
  kind: temporal.worker
  client: app:temporal_client
  task_queue: "my-app-queue"
  worker_options:
    # Идентичность
    identity: ""                          # Идентичность воркера (отображается в UI Temporal)

    # Параллелизм
    max_concurrent_activity_execution_size: 1000
    max_concurrent_workflow_task_execution_size: 1000
    max_concurrent_local_activity_execution_size: 1000
    max_concurrent_session_execution_size: 1000
    max_concurrent_eager_activity_execution_size: 0

    # Поллеры
    max_concurrent_activity_task_pollers: 20
    max_concurrent_workflow_task_pollers: 20

    # Ограничение скорости
    worker_activities_per_second: 0        # 0 = без ограничений
    worker_local_activities_per_second: 0
    task_queue_activities_per_second: 0

    # Тайм-ауты
    sticky_schedule_to_start_timeout: "5s"
    worker_stop_timeout: "0s"
    deadlock_detection_timeout: "0s"
    max_heartbeat_throttle_interval: "0s"
    default_heartbeat_throttle_interval: "0s"

    # Флаги
    enable_logging_in_replay: false
    enable_session_worker: false
    disable_workflow_worker: false
    local_activity_worker_only: false
    disable_eager_activities: false
    disable_registration_aliasing: false

    # Версионирование
    deployment_name: ""
    build_id: ""
    build_id: ${env:BUILD_ID}              # Чтение из реестра окружения
    use_versioning: false
    default_versioning_behavior: "pinned" # или "auto_upgrade"

Поля учётных данных и идентификаторов разрешают плейсхолдеры ${env:NAME} через реестр окружения при декодировании. Устаревшая директива build_id_env разрешается так же, но не рекомендуется; предпочитайте build_id: ${env:NAME}.

Поведение версионирования

default_versioning_behavior управляет тем, как новые запуски workflow выбирают build ID воркера, когда включён use_versioning:

Значение Поведение
pinned Workflow остаётся на том build ID, с которым был запущен, на всё время выполнения
auto_upgrade Workflow может возобновляться на последнем совместимом build ID после каждой задачи

build_id: ${env:NAME} читает build ID из реестра окружения, когда литеральный build_id не задан.

Session Worker

enable_session_worker: true позволяет воркеру выполнять Temporal Sessions: серию активностей, закреплённых за одним воркером (полезно, когда активности разделяют локальное состояние, например временный каталог или открытое соединение). max_concurrent_session_execution_size ограничивает количество одновременных сессий на воркере.

Значения по умолчанию для параллелизма

Параметр По умолчанию
max_concurrent_activity_execution_size 1000
max_concurrent_workflow_task_execution_size 1000
max_concurrent_local_activity_execution_size 1000
max_concurrent_session_execution_size 1000
max_concurrent_activity_task_pollers 20
max_concurrent_workflow_task_pollers 20
sticky_schedule_to_start_timeout 5s

Полный пример

version: "1.0"
namespace: app

entries:
  - name: temporal_client
    kind: temporal.client
    address: "localhost:7233"
    namespace: "default"
    lifecycle:
      auto_start: true

  - name: worker
    kind: temporal.worker
    client: app:temporal_client
    task_queue: "orders"
    lifecycle:
      auto_start: true
      depends_on:
        - app:temporal_client

  - name: order_workflow
    kind: workflow.lua
    source: file://order_workflow.lua
    method: main
    modules:
      - funcs
      - time
    meta:
      temporal:
        workflow:
          worker: app:worker

  - name: charge_payment
    kind: function.lua
    source: file://payment.lua
    method: charge
    modules:
      - http_client
      - json
    meta:
      temporal:
        activity:
          worker: app:worker

См. также

  • Activity — определение activity
  • Workflow — реализация workflow