Build reliable distributed workflows with Temporal, activity retries, and saga patterns in Google Antigravity
# Temporal Durable Workflows for Google Antigravity
Temporal enables reliable distributed execution. This guide covers workflow patterns optimized for Google Antigravity IDE and Gemini 3.
## Workflow Definition
```typescript
// workflows/orderWorkflow.ts
import { proxyActivities, sleep, condition, defineSignal, defineQuery, setHandler } from '@temporalio/workflow';
import type * as activities from '../activities';
const { validateOrder, processPayment, reserveInventory, shipOrder, sendNotification } =
proxyActivities<typeof activities>({
startToCloseTimeout: '30 seconds',
retry: {
initialInterval: '1 second',
backoffCoefficient: 2,
maximumAttempts: 5,
maximumInterval: '1 minute',
nonRetryableErrorTypes: ['InvalidOrderError', 'PaymentDeclinedError'],
},
});
// Signals and queries
export const cancelOrderSignal = defineSignal('cancelOrder');
export const orderStatusQuery = defineQuery<OrderStatus>('orderStatus');
interface OrderInput {
orderId: string;
customerId: string;
items: Array<{ productId: string; quantity: number; price: number }>;
paymentMethod: { type: string; token: string };
shippingAddress: Address;
}
type OrderStatus = 'pending' | 'validated' | 'paid' | 'reserved' | 'shipped' | 'completed' | 'cancelled';
export async function orderWorkflow(input: OrderInput): Promise<{ success: boolean; orderId: string }> {
let status: OrderStatus = 'pending';
let isCancelled = false;
// Set up signal handler for cancellation
setHandler(cancelOrderSignal, () => {
isCancelled = true;
});
// Set up query handler
setHandler(orderStatusQuery, () => status);
try {
// Step 1: Validate order
await validateOrder(input);
status = 'validated';
if (isCancelled) {
return handleCancellation(input.orderId, status);
}
// Step 2: Process payment
const paymentResult = await processPayment({
orderId: input.orderId,
amount: calculateTotal(input.items),
paymentMethod: input.paymentMethod,
});
status = 'paid';
if (isCancelled) {
// Refund payment if cancelled after payment
await refundPayment(paymentResult.transactionId);
return handleCancellation(input.orderId, status);
}
// Step 3: Reserve inventory
const reservationIds = await reserveInventory({
orderId: input.orderId,
items: input.items,
});
status = 'reserved';
if (isCancelled) {
// Release inventory and refund
await releaseInventory(reservationIds);
await refundPayment(paymentResult.transactionId);
return handleCancellation(input.orderId, status);
}
// Step 4: Ship order
const shipmentResult = await shipOrder({
orderId: input.orderId,
items: input.items,
address: input.shippingAddress,
});
status = 'shipped';
// Step 5: Send notification
await sendNotification({
type: 'order_shipped',
customerId: input.customerId,
data: {
orderId: input.orderId,
trackingNumber: shipmentResult.trackingNumber,
},
});
status = 'completed';
return { success: true, orderId: input.orderId };
} catch (error) {
// Compensating transactions handled by Temporal retry logic
throw error;
}
}
function calculateTotal(items: Array<{ price: number; quantity: number }>): number {
return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
async function handleCancellation(orderId: string, status: OrderStatus) {
await sendNotification({
type: 'order_cancelled',
customerId: '',
data: { orderId, cancelledAt: status },
});
return { success: false, orderId };
}
```
## Activity Implementations
```typescript
// activities/index.ts
import { ApplicationFailure } from '@temporalio/activity';
export async function validateOrder(order: OrderInput): Promise<void> {
// Validate order items exist
for (const item of order.items) {
const product = await db.product.findUnique({ where: { id: item.productId } });
if (!product) {
throw ApplicationFailure.nonRetryable(
`Product ${item.productId} not found`,
'InvalidOrderError'
);
}
if (product.price !== item.price) {
throw ApplicationFailure.nonRetryable(
'Price mismatch',
'InvalidOrderError'
);
}
}
}
export async function processPayment(input: PaymentInput): Promise<PaymentResult> {
try {
const result = await paymentGateway.charge({
amount: input.amount,
currency: 'USD',
source: input.paymentMethod.token,
metadata: { orderId: input.orderId },
});
return { transactionId: result.id, status: 'completed' };
} catch (error) {
if (error.code === 'card_declined') {
throw ApplicationFailure.nonRetryable(
'Payment declined',
'PaymentDeclinedError'
);
}
throw error; // Retry for other errors
}
}
export async function reserveInventory(input: ReservationInput): Promise<string[]> {
const reservationIds: string[] = [];
for (const item of input.items) {
const reservation = await db.inventoryReservation.create({
data: {
orderId: input.orderId,
productId: item.productId,
quantity: item.quantity,
expiresAt: new Date(Date.now() + 15 * 60 * 1000), // 15 min hold
},
});
reservationIds.push(reservation.id);
}
return reservationIds;
}
export async function shipOrder(input: ShipmentInput): Promise<ShipmentResult> {
const shipment = await shippingProvider.createShipment({
orderId: input.orderId,
items: input.items,
address: input.address,
});
return {
shipmentId: shipment.id,
trackingNumber: shipment.tracking_number,
carrier: shipment.carrier,
};
}
export async function sendNotification(input: NotificationInput): Promise<void> {
await notificationService.send({
type: input.type,
recipient: input.customerId,
data: input.data,
});
}
```
## Worker Configuration
```typescript
// worker.ts
import { Worker, NativeConnection } from '@temporalio/worker';
import * as activities from './activities';
async function run() {
const connection = await NativeConnection.connect({
address: process.env.TEMPORAL_ADDRESS || 'localhost:7233',
});
const worker = await Worker.create({
connection,
namespace: process.env.TEMPORAL_NAMESPACE || 'default',
taskQueue: 'order-processing',
workflowsPath: require.resolve('./workflows'),
activities,
maxConcurrentActivityTaskExecutions: 100,
maxConcurrentWorkflowTaskExecutions: 100,
});
await worker.run();
}
run().catch(console.error);
```
## Client Usage
```typescript
// client.ts
import { Client, Connection } from '@temporalio/client';
import { orderWorkflow, cancelOrderSignal, orderStatusQuery } from './workflows/orderWorkflow';
const client = new Client({ connection: await Connection.connect() });
// Start workflow
const handle = await client.workflow.start(orderWorkflow, {
args: [orderInput],
taskQueue: 'order-processing',
workflowId: `order-${orderId}',
});
// Query status
const status = await handle.query(orderStatusQuery);
// Cancel order
await handle.signal(cancelOrderSignal);
// Wait for result
const result = await handle.result();
```
## Best Practices
1. **Idempotency**: Design activities to be idempotent
2. **Timeouts**: Set appropriate timeouts for activities
3. **Retry Policies**: Configure retry for transient failures
4. **Signals**: Use signals for external events
5. **Queries**: Use queries for workflow state inspection
6. **Versioning**: Version workflows for safe updates
Google Antigravity's Gemini 3 can help design Temporal workflows for complex business processes and ensure reliability.This Temporal prompt is ideal for developers working on:
By using this prompt, you can save hours of manual coding and ensure best practices are followed from the start. It's particularly valuable for teams looking to maintain consistency across their temporal implementations.
Yes! All prompts on Antigravity AI Directory are free to use for both personal and commercial projects. No attribution required, though it's always appreciated.
This prompt works excellently with Claude, ChatGPT, Cursor, GitHub Copilot, and other modern AI coding assistants. For best results, use models with large context windows.
You can modify the prompt by adding specific requirements, constraints, or preferences. For Temporal projects, consider mentioning your framework version, coding style, and any specific libraries you're using.