Ever needed to test how your async job system would behave under different conditions? What if tasks fail? What if they take longer than expected? What if dependencies create bottlenecks?
Virtual Async is a Python simulator that lets you experiment with async job execution using virtual time - no waiting required. Instead of waiting real seconds or minutes, the simulator jumps instantly between events, making it perfect for rapid testing and debugging.
The simulator below runs entirely in your browser using Pyodide (Python compiled to WebAssembly). No server, no installation, just pure Python simulation magic.
The simulator uses virtual time - instead of waiting for real time to pass, it maintains an event queue and jumps directly to the next interesting moment. This means a task that would take 5 seconds in real time completes instantly in the simulation.
Tasks: Basic units of work with:
Sequential Tasks: Composite tasks containing subtasks that run in order
Event Queue: The heart of the simulation
The simulator comes pre-loaded with three tasks that demonstrate common patterns:
# Task 1: Fetch user data (fast, rarely fails)
fetch_user_001: 0.5-1.5s, 5% failure rate
# Task 2: Analyze data (slow, depends on task 1)
analyze_002: 2.0-5.0s, 15% failure rate, requires fetch_user_001
# Task 3: Upload results (sequential process, depends on task 2)
upload_003: Sequential task with 3 subtasks:
- prepare_data: 0.5-1.0s, 5% failure
- compress: 1.0-2.0s, 10% failure
- upload_to_s3: 1.5-3.0s, 20% failure
list
- See all tasks and their current statusstart
- Start all tasks with no dependenciesstart <task_id>
- Start a specific task (if dependencies met)step
- Process the next event in the queuerun
- Run the entire simulation to completioncheck <task_id>
- Get detailed info about a specific taskstatus
- View simulation statisticsreset
- Start over with a fresh simulationQuickly see how your system behaves when tasks fail. The simulator uses configurable failure probabilities to model real-world unreliability.
Visualize how task dependencies create execution patterns. See which tasks become bottlenecks and how failures cascade through the system.
Experiment with different task durations and concurrency patterns to understand system throughput without writing complex async code.
Perfect for demonstrating async execution patterns, dependency management, and failure handling without the complexity of real async frameworks.
The simulator is built with pure Python using only standard library features:
@dataclass
class Task:
task_id: str
duration_range: Tuple[float, float]
fail_probability: float
dependencies: List[str]
class Simulator:
def __init__(self):
self.tasks: Dict[str, Task] = {}
self.virtual_time: float = 0.0
self.event_queue: List[Event] = []
The entire implementation is ~300 lines of Python with no external dependencies, making it easy to understand, modify, and extend.
Want to add your own scenarios? The simulator is designed to be easily extensible:
Task
The code is structured to make these extensions straightforward - each concept (Task, Simulator, Event) is clearly separated and well-documented.
Traditional async testing requires:
Virtual time simulation solves these problems:
The simulator runs in your browser using:
This approach means:
The virtual async pattern can be applied to many domains:
The core insight is that by separating logical time from wall-clock time, we can test complex temporal behaviors quickly and reliably.
The full source code is available on GitHub. Feel free to fork, modify, and use it in your own projects. The simulator is designed to be embedded in documentation, tutorials, or testing frameworks.