CheatSheet
日本語 icon日本語English iconEnglish
チートシートとはカンニングペーパーのことです。それが転じて、本来覚えることをまとめておいたものです。
要点をすぐに参照できるようにまとめてみました。

Temporal

エンジニアのためのWebチートシート

Temporalは、障害に強い分散ワークフローオーケストレーションプラットフォームです。 Workflow、Activity、Worker、Signal/Query、リトライポリシー、CLIコマンドなどをチートシートにまとめました。

コア概念

基本コンポーネント

概念説明
Workflow決定論的なオーケストレーション関数。障害発生時も正確に再開できます。数秒〜数年にわたる実行をサポート。
Activity実際のビジネスロジック(I/O、API呼び出し、DB操作等)を実行するユニット。失敗・タイムアウト・リトライが可能。
WorkerTask Queueをポーリングし、Workflow/Activityを実行するプロセス。アプリケーションコードをホストします。
Task Queueワーカーがリッスンする名前付きバッファ。Workflowの実行をWorkerにルーティングします。
Signal実行中のWorkflowに送信できる外部イベント。ワークフローの挙動を動的に変更します。
QueryWorkflowの状態をリアルタイムに読み取る操作。状態を変更せずに現在の値を取得します。
Child WorkflowWorkflow内からネストして実行するサブWorkflow。複雑なプロセスの分割に使用します。
ContinueAsNew長期実行Workflowの履歴を新しい実行にリセットするパターン。メモリ効率を保ちます。
NamespaceWorkflowの論理的な分離単位。環境(dev/staging/prod)やチームごとに使い分けます。

Workflow定義

基本的なWorkflow

  • proxyActivitiesでActivityを呼び出すWorkflowの基本パターンです。

    import { proxyActivities, sleep } from '@temporalio/workflow';
    import type * as activities from './activities';
    
    const { processPayment, sendEmail, shipOrder } =
      proxyActivities<typeof activities>({
        startToCloseTimeout: '30s',
        retry: { maximumAttempts: 3 },
      });
    export async function orderWorkflow(order: OrderInput) {
      await processPayment(order);
      await sendEmail(order.email, 'Order confirmed!');
      await sleep('2 hours');  // Temporal timer (not setTimeout)
      return await shipOrder(order);
    }

並列Activity実行

  • Promise.allで複数のActivityを並列に実行するパターンです。

    export async function checkoutWorkflow(order: OrderInput) {
      // Run validations in parallel
      const [inventory, fraud, address] = await Promise.all([
        validateInventory(order.items),
        checkFraud(order.payment),
        verifyAddress(order.address),
      ]);
    
      if (!inventory.available) throw new Error('Out of stock');
      return { status: 'approved', address: address.normalized };
    }

Workflowの制約

ルール
決定論的であること(同じ入力で常に同じ結果を返す)
直接I/Oを行わない(I/OはActivityに委譲する)
setTimeout等のネイティブタイマーを使わない(workflow.sleep()を使う)
引数と戻り値はシリアライズ可能なJSON型であること
グローバル状態を変更しない
Math.random()を使わない(workflow.random()を使う)

Activity定義

基本的なActivity

  • 外部API呼び出しやDB操作を行うActivityの定義です。

    // activities.ts — I/O, API calls, DB operations
    export async function processPayment(order: OrderInput) {
      const res = await fetch('https://api.stripe.com/v1/charges', {
        method: 'POST',
        headers: { Authorization: `Bearer ${process.env.STRIPE_KEY}` },
        body: JSON.stringify({ amount: order.total, currency: 'jpy' }),
      });
      return res.json();
    }
    
    export async function sendEmail(to: string, subject: string) {
      await emailService.send({ to, subject });
    }
    
    export async function shipOrder(order: OrderInput) {
      return (await shippingApi.create(order)).id;
    }

ハートビート

  • 長時間実行するActivityで進捗を報告するパターンです。

    import { heartbeat } from '@temporalio/activity';
    
    export async function processLargeFile(filePath: string) {
      const lines = await readLines(filePath);
      for (let i = 0; i < lines.length; i++) {
        await processLine(lines[i]);
        if (i % 100 === 0) heartbeat({ processed: i });
      }
    }
    // Workflow side: set heartbeat timeout
    const { processLargeFile } = proxyActivities({
      startToCloseTimeout: '1 hour',
      heartbeatTimeout: '30s',
    });

Worker設定

Worker起動

  • WorkflowとActivityを実行するWorkerの設定です。

    // worker.ts
    import { Worker } from '@temporalio/worker';
    import * as activities from './activities';
    
    const worker = await Worker.create({
      workflowsPath: require.resolve('./workflows'),
      activities,
      taskQueue: 'order-processing',
    });
    await worker.run();

Workflowの開始(Client)

  • Temporal Clientを使ってWorkflowを開始するコードです。

    // client.ts
    import { Client } from '@temporalio/client';
    const client = new Client();
    
    // Start a workflow
    const handle = await client.workflow.start(orderWorkflow, {
      taskQueue: 'order-processing',
      workflowId: `order-${orderId}`,
      args: [{ id: orderId, items, email }],
    });
    
    const result = await handle.result();  // Wait for completion
    // Get handle to existing workflow
    const existing = client.workflow.getHandle('order-12345');
    const status = await existing.describe();

シグナル & クエリ

シグナル定義

  • 外部からWorkflowに送信するシグナルの定義と受信パターンです。

    import { defineSignal, setHandler, condition }
      from '@temporalio/workflow';
    
    export const approvalSignal = defineSignal<[boolean]>('approval');
    export async function approvalWorkflow(req: Request) {
      let approved: boolean | undefined;
    
      setHandler(approvalSignal, (v) => { approved = v; });
    
      // Wait up to 7 days for signal
      await condition(() => approved !== undefined, '7 days');
      return approved ? 'approved' : 'rejected';
    }

クエリ定義

  • Workflowの状態を読み取るクエリの定義パターンです。

    import { defineQuery, setHandler } from '@temporalio/workflow';
    
    export const statusQuery = defineQuery<string>('status');
    export const progressQuery = defineQuery<number>('progress');
    export async function processingWorkflow(items: Item[]) {
      let status = 'running', progress = 0;
      setHandler(statusQuery, () => status);
      setHandler(progressQuery, () => progress);
    
      for (const item of items) {
        await processItem(item);
        progress++;
      }
      status = 'completed';
    }

外部からのシグナル送信

  • Clientを使ってWorkflowにシグナルを送信するコードです。

    // client-usage.ts
    const handle = client.workflow.getHandle(
      'approval-workflow-123'
    );
    
    // Send signal
    await handle.signal(approvalSignal, true);
    
    // Send query
    const status = await handle.query(statusQuery);
    const progress = await handle.query(progressQuery);

リトライ & タイムアウト

タイムアウト種別

タイムアウト対象
Workflow Execution Timeoutリトライ・ContinueAsNew含む全体の実行時間上限
Workflow Run Timeout単一Workflow実行の時間上限
Schedule-To-Close TimeoutActivityがスケジュールされてから完了するまでの上限(リトライ含む)
Start-To-Close TimeoutActivityの1回の実行時間上限
Schedule-To-Start TimeoutActivityがスケジュールされてから開始するまでの上限
Heartbeat Timeoutハートビート間隔の上限(超過するとActivityがタイムアウト)

リトライポリシー

  • Activity Retry Policy

    const { riskyActivity } = proxyActivities({
      startToCloseTimeout: '30s',
      retry: {
        initialInterval: '1s',
        backoffCoefficient: 2,
        maximumInterval: '30s',
        maximumAttempts: 5,         // 0 = unlimited
        nonRetryableErrorTypes: ['InvalidInputError'],
      },
    });
  • Workflow-level Timeout

    const handle = await client.workflow.start(myWorkflow, {
      taskQueue: 'my-queue',
      workflowId: 'wf-1',
      workflowExecutionTimeout: '24 hours',
      workflowRunTimeout: '1 hour',
    });

CLIコマンド

開発サーバー

コマンド説明
temporal server start-devローカル開発サーバーを起動します。

Workflow操作

コマンド説明
temporal workflow start --task-queue q --type WfWorkflowの実行を開始します。
temporal workflow describe -w <id>Workflowの詳細情報を表示します。
temporal workflow listWorkflowの一覧を表示します。
temporal workflow show -w <id>Workflowのイベント履歴を表示します。
temporal workflow signal -w <id> --name sig実行中のWorkflowにシグナルを送信します。
temporal workflow query -w <id> --name qWorkflowにクエリを送信します。
temporal workflow terminate -w <id>Workflowを強制終了します。
temporal workflow cancel -w <id>Workflowにキャンセルリクエストを送信します。
temporal workflow reset -w <id> --event-id NWorkflowを特定のポイントからリセットします。

その他

コマンド説明
temporal task-queue describe --task-queue qTask Queueの情報を表示します。
temporal activity complete -w <id> -a <aid>Activityの完了を手動で報告します。
temporal activity fail -w <id> -a <aid>Activityの失敗を手動で報告します。
temporal env get環境設定を表示します。

デプロイ & エコシステム

Temporal Cloud vs Self-Hosted

特性Temporal CloudSelf-Hosted
説明フルマネージド完全な制御
Scaling自動スケーリング自己メンテナンス
Cost従量課金Infra + Ops

対応SDK

言語ステータス
Go最も成熟したSDK
Java安定版・エンタープライズ利用多数
TypeScript急成長中・人気No.1
Python安定版
.NET安定版
PHPコミュニティサポート