Что такое Temporal и для чего он используется?

Ответ

Temporal — это open-source платформа для оркестрации распределённых, отказоустойчивых и долгоживущих процессов, которые называются воркфлоу (workflows).

Простыми словами, Temporal позволяет писать сложную бизнес-логику (например, процесс оформления заказа в интернет-магазине) как единый последовательный код, а платформа сама заботится о сохранении состояния, повторных попытках (retries), таймаутах и восстановлении после сбоев.

Ключевые компоненты

  1. Workflow: Код, описывающий бизнес-логику. Он детерминирован и может «жить» очень долго (дни, месяцы). Его состояние надёжно сохраняется.
  2. Activity: Код, выполняющий реальную работу (например, вызов внешнего API, запись в базу данных, отправка email). В отличие от Workflow, Activity может иметь побочные эффекты и не является детерминированным.
  3. Worker: Процесс, который хостит и выполняет код Workflow и Activity, опрашивая сервер Temporal на предмет новых задач.

Основные преимущества

  • Надёжность: Воркфлоу переживают сбои воркеров, серверов и сети. Temporal гарантирует, что воркфлоу будет выполнен до конца.
  • Видимость (Visibility): Предоставляет инструменты для отслеживания состояния, истории и отладки каждого экземпляра воркфлоу.
  • Масштабируемость: Архитектура позволяет горизонтально масштабировать воркеры для обработки большой нагрузки.

Пример использования в Go

// Workflow определяет последовательность шагов
func OrderProcessingWorkflow(ctx workflow.Context, orderID string) (string, error) {
    // Настраиваем таймауты для Activity
    ao := workflow.ActivityOptions{
        StartToCloseTimeout: 10 * time.Second,
    }
    ctx = workflow.WithActivityOptions(ctx, ao)

    // 1. Списать деньги
    var chargeResult string
    err := workflow.ExecuteActivity(ctx, ChargeCustomerActivity, orderID).Get(ctx, &chargeResult)
    if err != nil {
        return "", err
    }

    // 2. Отправить заказ на склад
    err = workflow.ExecuteActivity(ctx, ShipOrderActivity, orderID).Get(ctx, nil)
    if err != nil {
        return "", err
    }

    return "Order completed", nil
}

// Activity выполняет реальную работу
func ChargeCustomerActivity(ctx context.Context, orderID string) (string, error) {
    // ... логика обращения к платёжному шлюзу ...
    return "charged", nil
}

Temporal идеально подходит для сложных бизнес-процессов, где важна гарантия выполнения: обработка заказов, онбординг пользователей, ETL-пайплайны, SAGA-паттерн в микросервисах.

Ответ 18+ 🔞

А, так вот оно что, Temporal! Ну это ж, блядь, такая штука, которая за тебя думает, как не облажаться с этими, сука, долгими и сложными процессами!

Представь себе: пишешь ты код для оформления заказа, как будто он простой и линейный — списали бабки, отправили на склад, всё дела. А на самом деле там сервисы падают, сети глючат, и в целом пиздец. Так вот, Temporal берёт твой красивый, последовательный код и говорит: «Не парься, чувак, я за тебя всё сохраню, перезапущу, если что, и доведу до конца, даже если пол-интернета сгорит». Ебать, как удобно!

Из чего состоит эта магия:

  1. Воркфлоу (Workflow): Это твоя главная бизнес-песня. Ты пишешь её как обычный код: сделай раз, сделай два. Он может выполняться хоть год, а его состояние не потеряется, даже если ты сервер вырубишь. Детерминированный, блядь, как часы.
  2. Активность (Activity): А это уже пошла реальная работа с внешним миром — пнуть API, ткнуть в базу, письмо отправить. Тут уже может быть всякая недетерминированная хуйня, но Temporal и за этим присмотрит.
  3. Воркер (Worker): Это такой трудяга-процесс, который тупо слушает сервер и кричит: «Давай сюда задачи! Я их выполню!». Масштабируешь их — овердохуища.

Чем это всё, блядь, круто:

  • Не убьёшь: Воркфлоу переживёт падение воркеров, серверов и прочие катаклизмы. Гарантия выполнения — железная.
  • Видно всё: Можно в любой момент залезть и посмотреть, на каком этапе какой процесс завис, и почему. Отладка — просто песня.
  • Масштабируется: Накинул воркеров — и поехали обрабатывать тонны запросов. Красота!

Вот смотри, как это выглядит в коде (Go):

// Это наш главный воркфлоу — процесс заказа
func OrderProcessingWorkflow(ctx workflow.Context, orderID string) (string, error) {
    // Говорим, сколько ждать каждую активность
    ao := workflow.ActivityOptions{
        StartToCloseTimeout: 10 * time.Second,
    }
    ctx = workflow.WithActivityOptions(ctx, ao)

    // 1. Списать деньги с клиента (ой, надеюсь, он не обидится)
    var chargeResult string
    err := workflow.ExecuteActivity(ctx, ChargeCustomerActivity, orderID).Get(ctx, &chargeResult)
    if err != nil {
        return "", err // Если не получилось — ну, пидарас, не повезло с картой
    }

    // 2. Отправить заказ на склад
    err = workflow.ExecuteActivity(ctx, ShipOrderActivity, orderID).Get(ctx, nil)
    if err != nil {
        return "", err // А тут, возможно, на складе все перепились
    }

    return "Order completed", nil // Ура, товар уехал!
}

// А это уже активность — реальное действие
func ChargeCustomerActivity(ctx context.Context, orderID string) (string, error) {
    // ... тут идём в платёжный шлюз и молимся ...
    return "charged", nil
}

Короче, Temporal — это твой личный надёжный завхоз для сложных процессов. Оформление заказов, онбординг пользователей, эти ваши SAGA в микросервисах — везде, где нужно гарантированно доползти из точки А в точку Б, не сломавшись посередине. Ёпта, гениальная штука!