Wait
Waits for and dequeues an element from an in-memory queue with optional timeout. This is a blocking operation that waits until an element becomes available or the timeout expires.
Common Properties
- Name - The custom name of the node.
- Color - The custom color of the node.
- Delay Before (sec) - Waits in seconds before executing the node.
- Delay After (sec) - Waits in seconds after executing the node.
- Continue On Error - Automation will continue regardless of any error. The default value is false.
If the ContinueOnError property is true, no error is caught when the project is executed, even if a Catch node is used.
Inputs
- Queue ID - The unique queue identifier returned from the Create Queue node.
Output
- Element - The element dequeued from the queue. The data type matches the type that was enqueued (string, object, array, etc.).
Options
- Timeout (ms) - Maximum time to wait for an element in milliseconds. Set to 0 to wait indefinitely until an element is available.
How It Works
The Wait node blocks execution until an element is available in the queue. When executed, the node:
- Validates the Queue ID exists
- Retrieves the queue from memory
- Checks if the queue has elements
- If element available: Removes and returns it immediately
- If queue empty: Waits for an element to be enqueued
- If timeout specified: Returns error if timeout expires before element available
- If timeout is 0: Waits indefinitely until element arrives
This is the blocking version of Dequeue, ideal for producer-consumer patterns.
Examples
Example 1: Wait Indefinitely
Wait forever until an item is available:
Inputs:
- Queue ID: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
Options:
- Timeout (ms): 0
Behavior:
- Blocks execution until an element is enqueued
- No timeout - waits forever if needed
- Perfect for consumer flows
Example 2: Wait with Timeout
Wait up to 30 seconds for an item:
Inputs:
- Queue ID: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
Options:
- Timeout (ms): 30000
Behavior:
- Waits up to 30 seconds for an element
- Returns element if available within timeout
- Returns error if timeout expires
Example 3: Producer-Consumer Pattern
Producer Flow:
1. Create Queue → queueId
2. Share queueId with consumer
3. Loop through data:
- Process data
- Enqueue result to queueId
4. When done, enqueue "DONE" signal
Consumer Flow:
1. Receive queueId from producer
2. Loop:
- Wait (Queue ID: queueId, Timeout: 0) → item
- If item == "DONE":
- Break loop
- Process item
3. Delete Queue
Example 4: Parallel Workers
Multiple consumers waiting for work:
Producer Flow:
1. Create Queue → workQueueId
2. Enqueue 100 tasks
3. Wait for consumers to finish
Consumer Flows (3 parallel):
1. Receive workQueueId
2. While true:
- Try:
- Wait (Queue ID: workQueueId, Timeout: 5000) → task
- Process task
- Catch (timeout):
- Log "No more work"
- Break
Example 5: Event Processing
Wait for events to arrive and process them:
1. Create Queue → eventQueueId
2. Start event listener (enqueues to queue)
3. Loop:
- Wait (Queue ID: eventQueueId, Timeout: 60000) → event
- Process event
- If event.type == "shutdown":
- Break
4. Delete Queue
Use Cases
- Producer-consumer patterns - Consumers wait for producers to add items
- Event processing - Wait for events to arrive from async sources
- Job queue processing - Workers wait for jobs to be available
- Parallel processing - Multiple workers consuming from shared queue
- Real-time processing - Block until new data arrives
- Batch collection - Wait for batch to fill before processing
Error Handling
The node will return errors in the following cases:
- ErrInvalidArg - Queue ID or timeout value is invalid
- ErrNotFound - Queue with the specified ID does not exist
- Context timeout error - Timeout expired before element was available
- ErrInternal - Failed to set output or internal queue error
Common Errors and Solutions
Error: "context deadline exceeded" (Timeout)
Cause: No element was enqueued before timeout expired.
Solution:
Option 1 - Increase timeout:
- Set higher timeout value
- Or set to 0 for no timeout
Option 2 - Handle gracefully:
- Try:
- Wait with timeout
- Catch:
- Log "No items available"
- Exit or retry
Option 3 - Check producer:
- Verify producer is running
- Check for producer errors
- Ensure items are being enqueued
Error: "queue with id ... does not exist"
Cause: Queue was deleted or never created.
Solution:
- Ensure Create Queue succeeded
- Share correct Queue ID between flows
- Don't delete queue while consumers waiting
- Verify Queue ID variable is in scope
Tips and Best Practices
- Timeout strategy - Use 0 for infinite wait in reliable producer-consumer setups
- Graceful shutdown - Enqueue sentinel value (e.g., "DONE") to signal completion
- Error handling - Handle timeout errors to prevent flow crashes
- Multiple consumers - Safe to have multiple flows waiting on same queue
- Producer checks - Ensure producer is running before starting consumers
- Resource cleanup - Delete queue only after all consumers finish
- Logging - Log when waiting and when items received for debugging
Performance Considerations
- Blocking operation - Flow execution stops until element available or timeout
- Efficient waiting - No polling loop, uses event-based waiting
- Thread-safe - Multiple consumers can wait concurrently
- Low CPU usage - Doesn't consume CPU while waiting
- FIFO guarantee - First consumer waiting gets first element enqueued
- Immediate on available - Returns immediately if element already in queue
Wait vs Dequeue
| Feature | Wait | Dequeue |
|---|---|---|
| Blocks when empty | Yes | No |
| Timeout support | Yes | No |
| Empty queue behavior | Waits | Error |
| Use case | Producer-consumer | Known items |
| CPU usage | Low (event-based) | N/A |
Choose Wait when:
- Items arrive asynchronously
- Want to block until item available
- Implementing producer-consumer pattern
- Processing real-time events
- Multiple consumers on shared queue
Choose Dequeue when:
- Know items are available
- Want immediate error if empty
- Processing in counted loop
- Don't want blocking behavior
Timeout Values
| Timeout | Behavior | Use Case |
|---|---|---|
| 0 | Wait forever | Reliable producer-consumer |
| Small (1-5s) | Quick timeout | Checking for items |
| Medium (30-60s) | Standard wait | Normal processing |
| Large (5+ min) | Long wait | Slow producers |
Processing Patterns
Pattern 1: Infinite Consumer Loop
1. Create Queue → queueId
2. Loop:
- Wait (Timeout: 0) → item
- If item == "STOP":
- Break
- Process item
3. Delete Queue
Pattern 2: Timeout-Based Exit
1. Loop:
- Try:
- Wait (Timeout: 30000) → item
- Process item
- Catch (timeout):
- Log "Idle for 30s, exiting"
- Break
Pattern 3: Parallel Workers
Worker Flow (run 5 instances):
1. Receive queueId
2. While true:
- Try:
- Wait (Timeout: 10000) → task
- Process task
- Catch:
- Break when idle
Pattern 4: Event-Driven Processing
1. Create Queue → eventQueue
2. Start async event source → enqueues to eventQueue
3. Loop:
- Wait (Timeout: 0) → event
- Handle event
- If event.type == "exit":
- Break
Integration Examples
Example: Web Scraping with Multiple Workers
Main Flow:
1. Create Queue → urlQueueId
2. Scrape listing page → urls
3. For each url:
- Enqueue url to urlQueueId
4. Enqueue "COMPLETE" signal
5. Wait for workers to finish
6. Delete Queue
Worker Flows (3 parallel instances):
1. Receive urlQueueId
2. Loop:
- Wait (Queue ID: urlQueueId, Timeout: 0) → url
- If url == "COMPLETE":
- Break
- Open Browser
- Navigate to url
- Extract data
- Save to database
- Close Browser
3. Log "Worker finished"
Example: Real-Time Data Processing
Data Collector Flow:
1. Create Queue → dataQueueId
2. Share with processor
3. Connect to API stream
4. On each data event:
- Enqueue event data
Processor Flow:
1. Receive dataQueueId
2. Loop:
- Wait (Queue ID: dataQueueId, Timeout: 120000) → data
- Transform data
- Save to database
- If shutdown_requested:
- Break
3. Delete Queue
Example: Batch Processing with Timeout
1. Create Queue → batchQueue
2. Start data source (enqueues items)
3. batch = []
4. Loop:
- Try:
- Wait (Queue ID: batchQueue, Timeout: 5000) → item
- Add item to batch
- If batch.length >= 100:
- Process batch
- Clear batch
- Catch (timeout):
- If batch.length > 0:
- Process remaining batch
- Break
5. Delete Queue
Concurrency and Thread Safety
Wait node is thread-safe for concurrent access:
Flow 1: Flow 2: Flow 3:
Wait → gets item1 Wait → gets item2 Wait → gets item3
Process item1 Process item2 Process item3
Wait → gets item4 Wait → gets item5 Wait → gets item6
- Each consumer gets unique items
- FIFO order maintained across all consumers
- No race conditions or data corruption
- Safe for parallel flow execution
Graceful Shutdown Patterns
Pattern: Sentinel Value
Producer:
1. Enqueue all work items
2. Enqueue "STOP" for each consumer
Consumers:
1. Loop:
- Wait → item
- If item == "STOP": Break
- Process item
Pattern: Timeout-Based
Consumer:
1. Loop:
- Try:
- Wait (Timeout: 30000) → item
- Process item
- Catch timeout:
- Assume no more work
- Break
Pattern: Count-Based
Producer:
1. Enqueue N items
2. Set shared variable: total_items = N
Consumer:
1. processed = 0
2. Loop while processed < total_items:
- Wait → item
- Process item
- processed += 1
Advanced Use Cases
Load Balancing
Multiple workers automatically balanced by queue:
- Workers wait when idle
- First available worker gets next item
- Natural load distribution
Priority Handling
Use multiple queues with different priorities:
1. Create Queue → highPriorityQueue
2. Create Queue → lowPriorityQueue
3. Loop:
- Try:
- Wait (highPriorityQueue, Timeout: 100) → item
- Catch:
- Wait (lowPriorityQueue, Timeout: 5000) → item
- Process item
Circuit Breaker
Timeout can implement circuit breaker pattern:
1. failures = 0
2. Loop:
- Try:
- Wait (Timeout: 10000) → item
- Process item
- failures = 0
- Catch timeout:
- failures += 1
- If failures > 3:
- Log "Circuit open"
- Break