async-queue-temporal-expert · git:20260907.82c61cd · 2026-09-07 · sha256 cb2c0e807935de80
async-queue-temporal-expert git:20260907.82c61cdA
Immutable. This exact content never changes and is served at /api/v1/blob/cb2c0e807935de80.
---
name: async-queue-temporal-expert
description: "Expert guide for Durable Workflow Engines (Temporal.io, Trigger.dev v3, Inngest, BullMQ v5) and fault-tolerant background sagas / Panduan ahli workflow engine tahan-gagal (Temporal, Trigger.dev, Inngest, BullMQ)."
author: "Roedy Rustam"
---
# Async Queue & Durable Workflow Expert (Temporal & Sagas 2026)
[English](#english) | [Bahasa Indonesia](#bahasa-indonesia)
---
<a name="english"></a>
## English
### Purpose & Overview
Production-grade architectural guide for designing durable, fault-tolerant background execution pipelines, asynchronous job queues, and distributed state machines using **Temporal.io**, **Trigger.dev v3**, **Inngest**, and **BullMQ v5**. Guarantees eventual completion across long-running sagas, API rate limits, worker crashes, and network partitions.
### Key Capabilities
1. **Durable State Machines**: Workflows survive process restarts, deployments, and database blips without losing state or re-executing completed side-effects.
2. **Distributed Saga Pattern**: Multi-step transactions paired with automated compensating activities (rollbacks) whenever a downstream service permanently fails.
3. **Idempotency & Deduplication**: Ensuring unique idempotency keys per transaction to prevent double billing or duplicate emails.
4. **Queue Concurrency & Rate Limiting**: Token-bucket throttles, exponential backoff with jitter, and dead-letter queues (DLQ) for poison-pill isolation.
---
### Production Implementation Recipes
#### Recipe 1: Temporal.io Saga Pattern with Compensations (TypeScript SDK)
```typescript
import { proxyActivities, ApplicationFailure } from '@temporalio/workflow';
import type * as activities from './activities';
// Proxy activities with aggressive retry policies
const { chargeCustomer, provisionLicense, sendWelcomeEmail, refundCustomer, revokeLicense } =
proxyActivities<typeof activities>({
startToCloseTimeout: '1 minute',
retry: {
initialInterval: '1s',
backoffCoefficient: 2,
maximumAttempts: 5,
nonRetryableErrorTypes: ['InvalidCardError', 'AccountSuspendedError'],
},
});
export interface SubscriptionWorkflowInput {
customerId: string;
planId: string;
amountCents: number;
}
/**
* Distributed Subscription Saga with Compensating Rollbacks
*/
export async function subscriptionSagaWorkflow(input: SubscriptionWorkflowInput): Promise<{ status: string }> {
const compensations: Array<() => Promise<void>> = [];
try {
// Step 1: Charge Customer
const chargeResult = await chargeCustomer(input.customerId, input.amountCents);
compensations.unshift(() => refundCustomer(chargeResult.chargeId));
// Step 2: Provision License
const licenseResult = await provisionLicense(input.customerId, input.planId);
compensations.unshift(() => revokeLicense(licenseResult.licenseId));
// Step 3: Send Welcome Notification
await sendWelcomeEmail(input.customerId, licenseResult.licenseKey);
return { status: 'COMPLETED' };
} catch (error) {
// Execute compensating activities in reverse order
for (const compensate of compensations) {
try {
await compensate();
} catch (compError) {
console.error('Compensation failed, alerting on-call engineer:', compError);
}
}
throw ApplicationFailure.create({
message: `Subscription saga failed and rolled back: ${(error as Error).message}`,
nonRetryable: true,
});
}
}
```
#### Recipe 2: Trigger.dev v3 Durable Task with Idempotency
```typescript
import { task } from '@trigger.dev/sdk/v3';
export const generateEnterpriseAnalyticsReport = task({
id: 'generate-enterprise-report',
retry: {
maxAttempts: 4,
minTimeoutInMs: 2000,
factor: 2,
randomize: true, // Jitter
},
run: async (payload: { tenantId: string; month: string }, { ctx }) => {
// Automatic checkpointing: each step runs durably
const data = await ctx.run('fetch-telemetry', async () => {
return await fetchTelemetryFromWarehouse(payload.tenantId, payload.month);
});
const pdfUrl = await ctx.run('render-pdf', async () => {
return await generateReportPdf(data);
});
await ctx.run('dispatch-webhook', async () => {
return await sendWebhookNotification(payload.tenantId, pdfUrl);
});
return { success: true, pdfUrl };
},
});
```
---
### Implementation Checklist
- [ ] Implement Saga rollback handlers for multi-step distributed payments and user provisioning.
- [ ] Enforce deterministic code inside Temporal workflows (never use `Math.random()`, `Date.now()`, or direct DB calls in workflow files; run them inside activities).
- [ ] Store large payloads in object storage (S3/R2); pass only IDs and signed URLs through queues.
- [ ] Configure DLQ (Dead Letter Queue) and alert thresholds for persistent failures.
## Orchestration & Integration
- Integrates with: `js-backend-expert`, `background-jobs-queue-expert`, `error-resilience-expert`, `saas-billing`, `doku-payment-gateway`.
---
<a name="bahasa-indonesia"></a>
## Bahasa Indonesia
### Tujuan & Gambaran Umum
Panduan arsitektur tingkat produksi untuk merancang pipeline eksekusi background yang tahan-gagal (durable execution), antrean tugas asinkron, dan state machine terdistribusi menggunakan **Temporal.io**, **Trigger.dev v3**, **Inngest**, dan **BullMQ v5**. Menjamin penyelesaian mutlak tugas berdurasi panjang terhadap pembatasan rate limit API, kegagalan worker, dan partisi jaringan.
### Kemampuan Utama
1. **State Machine Tahan-Gagal (Durable Execution)**: Alur kerja (workflow) tetap bertahan saat restart server, deployment, atau gangguan database tanpa kehilangan progres state.
2. **Pola Transaksi Terdistribusi (Saga Pattern)**: Transaksi multi-langkah yang dilengkapi dengan aktivitas kompensasi (rollback otomatis) jika langkah lanjutan gagal permanen.
3. **Idempotensi & Anti-Duplikasi**: Menjamin kunci idempotensi unik pada setiap transaksi guna mencegah duplikasi penagihan atau email berulang.
4. **Pembatasan Rate Limit & DLQ**: Throttling berbasis token bucket, exponential backoff dengan jitter acak, dan dead-letter queue (DLQ) untuk mengisolasi tugas beracun (*poison pills*).
---
### Resep Implementasi Produksi
#### Resep 1: Pola Saga Temporal.io dengan Logika Kompensasi (TypeScript)
```typescript
import { proxyActivities, ApplicationFailure } from '@temporalio/workflow';
import type * as activities from './activities';
const { tagihPelanggan, aktifkanLisensi, kirimEmailSambutan, kembalikanDana, cabutLisensi } =
proxyActivities<typeof activities>({
startToCloseTimeout: '1 minute',
retry: {
initialInterval: '1s',
backoffCoefficient: 2,
maximumAttempts: 5,
},
});
export interface InputWorkflowLangganan {
customerId: string;
planId: string;
amountCents: number;
}
export async function workflowSagaLangganan(input: InputWorkflowLangganan) {
const kompensasi: Array<() => Promise<void>> = [];
try {
// Langkah 1: Tagih Pembayaran
const hasilTagihan = await tagihPelanggan(input.customerId, input.amountCents);
kompensasi.unshift(() => kembalikanDana(hasilTagihan.chargeId));
// Langkah 2: Aktifkan Lisensi
const hasilLisensi = await aktifkanLisensi(input.customerId, input.planId);
kompensasi.unshift(() => cabutLisensi(hasilLisensi.licenseId));
// Langkah 3: Kirim Notifikasi
await kirimEmailSambutan(input.customerId, hasilLisensi.licenseKey);
return { status: 'SELESAI' };
} catch (error) {
// Eksekusi kompensasi rollback secara berurutan mundur
for (const compensate of kompensasi) {
try {
await compensate();
} catch (err) {
console.error('Kompensasi gagal:', err);
}
}
throw ApplicationFailure.create({
message: `Saga gagal dan dilakukan rollback: ${(error as Error).message}`,
nonRetryable: true,
});
}
}
```
#### Resep 2: Tugas Background Tahan-Gagal Trigger.dev v3
```typescript
import { task } from '@trigger.dev/sdk/v3';
export const buatLaporanAnalitik = task({
id: 'buat-laporan-analitik',
retry: {
maxAttempts: 4,
factor: 2,
randomize: true, // Jitter
},
run: async (payload: { tenantId: string; bulan: string }, { ctx }) => {
const data = await ctx.run('ambil-data', async () => {
return await ambilDataWarehouse(payload.tenantId, payload.bulan);
});
const urlPdf = await ctx.run('buat-pdf', async () => {
return await renderDokumenPdf(data);
});
await ctx.run('kirim-webhook', async () => {
return await notifikasiWebhook(payload.tenantId, urlPdf);
});
return { sukses: true, urlPdf };
},
});
```
---
### Checklist Implementasi
- [ ] Terapkan penanganan rollback (Saga) untuk alur transaksi pembayaran dan provisi akun bertahap.
- [ ] Pastikan kode di dalam alur Temporal selalu deterministik (jangan gunakan `Math.random()` atau kueri DB langsung di dalam workflow, tempatkan di dalam activities).
- [ ] Pindahkan berkas besar ke S3/R2 dan hanya teruskan referensi ID melalui queue.
- [ ] Pasang konfigurasi DLQ (Dead Letter Queue) dan notifikasi peringatan jika ada job yang macet.
## Integrasi Orkestrasi
- Terintegrasi dengan: `js-backend-expert`, `background-jobs-queue-expert`, `error-resilience-expert`, `saas-billing`, `doku-payment-gateway`.