|
1 | 1 | # Temporal + Stagehand Integration
|
2 | 2 |
|
3 |
| -A simplified example showing how Temporal handles browser automation failures with automatic retries. |
| 3 | +A best practices example showing how Temporal handles browser automation failures with automatic retries using atomic, idempotent activities. |
4 | 4 |
|
5 | 5 | ## What it does
|
6 | 6 |
|
7 | 7 | - Uses Stagehand to perform Google searches in a real browser
|
8 |
| -- Temporal automatically retries when browser sessions fail |
9 |
| -- No artificial failure simulation - relies on real network/browser issues |
10 |
| -- Clean, simple code focused on the retry pattern |
| 8 | +- Demonstrates Temporal best practices with atomic activities |
| 9 | +- Each activity handles a single responsibility |
| 10 | +- Temporal automatically retries individual steps on failure |
| 11 | +- Clean, maintainable code following Temporal patterns |
| 12 | + |
| 13 | +## Temporal Best Practices Demonstrated |
| 14 | + |
| 15 | +### Atomic Activities |
| 16 | +Each activity performs a single, well-defined task: |
| 17 | +1. **initializeBrowser** - Creates and initializes browser session |
| 18 | +2. **navigateToSearchPage** - Navigates to Google |
| 19 | +3. **executeSearch** - Types query and submits search |
| 20 | +4. **extractSearchResults** - Extracts and validates results |
| 21 | +5. **cleanupBrowser** - Closes browser session |
| 22 | +6. **formatResults** - Formats results for display |
| 23 | + |
| 24 | +### Why Atomic Activities? |
| 25 | +- **Efficient retries**: If extraction fails after search succeeds, only extraction is retried |
| 26 | +- **Better performance**: No need to repeat successful steps |
| 27 | +- **Clearer debugging**: Each activity's purpose is obvious |
| 28 | +- **Flexible retry policies**: Different activities can have different retry strategies |
| 29 | + |
| 30 | +### Idempotent Design |
| 31 | +- Browser sessions are reused if already initialized |
| 32 | +- Cleanup handles already-closed sessions gracefully |
| 33 | +- Navigation always results in the same state |
| 34 | +- Formatting produces consistent output |
11 | 35 |
|
12 | 36 | ## Setup
|
13 | 37 |
|
@@ -43,38 +67,39 @@ npm run demo "your search term" # Custom search
|
43 | 67 |
|
44 | 68 | ## How it Works
|
45 | 69 |
|
46 |
| -1. **Activities** (`research-activities.ts`): |
47 |
| - - `searchWeb`: Opens browser, searches Google, extracts results |
48 |
| - - `formatResults`: Formats results as readable text |
49 |
| - - Natural failures from network issues, timeouts, or page changes |
| 70 | +### Activities (`research-activities.ts`) |
| 71 | +Each activity is designed to be: |
| 72 | +- **Atomic**: Does one thing only |
| 73 | +- **Idempotent**: Can be safely retried |
| 74 | +- **Focused**: Clear single responsibility |
50 | 75 |
|
51 |
| -2. **Workflow** (`workflows.ts`): |
52 |
| - - `searchWithRetry`: Orchestrates the search with retry logic |
53 |
| - - Configured for up to 10 retries with exponential backoff |
54 |
| - - 2-minute timeout per attempt |
| 76 | +### Workflow (`workflows.ts`) |
| 77 | +- Orchestrates the atomic activities in sequence |
| 78 | +- Uses tailored retry policies for each activity type |
| 79 | +- Handles cleanup in a finally block |
| 80 | +- Provides clear progress logging |
55 | 81 |
|
56 |
| -3. **Worker** (`research-worker.ts`): |
57 |
| - - Processes workflow tasks |
58 |
| - - Limits to 2 concurrent browser sessions |
59 |
| - - Simple configuration focused on essentials |
| 82 | +### Worker (`research-worker.ts`) |
| 83 | +- Processes workflow tasks |
| 84 | +- Limits to 2 concurrent browser sessions |
| 85 | +- Simple configuration focused on essentials |
60 | 86 |
|
61 | 87 | ## Retry Behavior
|
62 | 88 |
|
63 |
| -Temporal automatically retries on failures like: |
64 |
| -- Network timeouts |
65 |
| -- Browser session crashes |
66 |
| -- Page load failures |
67 |
| -- Element not found errors |
| 89 | +Each activity has a custom retry policy based on its characteristics: |
68 | 90 |
|
69 |
| -The retry policy uses: |
70 |
| -- Initial interval: 2 seconds |
71 |
| -- Maximum interval: 20 seconds |
72 |
| -- Backoff coefficient: 1.8x |
73 |
| -- Maximum attempts: 10 |
| 91 | +- **Initialize Browser**: 5 attempts, 2-10 second intervals |
| 92 | +- **Navigate**: 8 attempts, 1-5 second intervals (fast retries) |
| 93 | +- **Execute Search**: 10 attempts, 2-15 second intervals |
| 94 | +- **Extract Results**: 10 attempts, 3-20 second intervals (most likely to fail) |
| 95 | +- **Cleanup**: 3 attempts, 1-3 second intervals |
| 96 | +- **Format**: 2 attempts, minimal retry (deterministic) |
74 | 97 |
|
75 | 98 | ## Benefits
|
76 | 99 |
|
77 | 100 | - **Simplicity**: Clean code without complex error handling
|
| 101 | +- **Efficiency**: Only failed steps are retried |
78 | 102 | - **Reliability**: Temporal ensures tasks complete or fail definitively
|
79 | 103 | - **Visibility**: Monitor progress in Temporal Web UI at http://localhost:8233
|
80 |
| -- **Real-world**: Tests actual browser issues, not simulated failures |
| 104 | +- **Maintainability**: Each activity can be tested and updated independently |
| 105 | +- **Flexibility**: Easy to add new steps or modify retry behavior |
0 commit comments