How MiroFish Handles Asynchronous Tasks for Long-Running Simulations

MiroFish leverages Python's asyncio framework with a global shutdown event, signal handlers, and asyncio.gather() to execute Twitter and Reddit simulations concurrently while maintaining responsive control over potentially endless processes.

The 666ghj/mirofish repository implements a sophisticated asynchronous architecture to manage long-running social media simulations. By utilizing Python's native asyncio library, the system can execute complex Twitter and Reddit simulations without blocking the interpreter, while providing robust mechanisms for graceful shutdown and external command integration.

Core Async Architecture

Global Event Loop and Shutdown Coordination

At the heart of the system is a global asyncio.Event named _shutdown_event, instantiated in backend/scripts/run_parallel_simulation.py (lines 25-28). This event serves as a coordination mechanism that all coroutines monitor to detect termination requests.


# From run_parallel_simulation.py lines 25-28

_shutdown_event = asyncio.Event()

def signal_handler(signum, frame):
    logger.info(f"Received signal {signum}, shutting down...")
    _shutdown_event.set()

Async Simulation Loops

Each platform simulation runs as an independent async def coroutine. The run_twitter_simulation and run_reddit_simulation functions (lines 28-34) implement the main execution loops that repeatedly determine active agents, build dictionaries of LLMAction() objects, execute await env.step(actions), and read SQLite traces to log actions.

Execution Control and Resource Management

Round Limiting via CLI

To prevent infinite execution, the system accepts a --max-rounds parameter through the CLI. In run_parallel_simulation.py (lines 20-24), the configuration-derived round count is truncated to this limit, enabling controlled testing and CI/CD integration.

python backend/scripts/run_parallel_simulation.py \
  --config simulations/run1/simulation_config.json \
  --max-rounds 200

Graceful Shutdown Implementation

The system registers signal handlers for SIGINT and SIGTERM in setup_signal_handlers (lines 63-72). When triggered, the handler sets _shutdown_event, which unblocks coroutines waiting on await asyncio.wait_for(_shutdown_event.wait(), timeout=0.5). The environments then close via await env.close() before the process exits cleanly.

Parallel Execution and IPC

Concurrent Platform Simulation

When neither --twitter-only nor --reddit-only flags are present, the system launches both simulations concurrently using asyncio.gather() (lines 84-88). Each platform maintains independent loggers and SQLite databases while sharing the global shutdown event for coordinated termination.


# From run_parallel_simulation.py lines 84-88

await asyncio.gather(
    run_twitter_simulation(twitter_env, config, logger, max_rounds),
    run_reddit_simulation(reddit_env, config, logger, max_rounds)
)

Post-Simulation Command Interface

After completing the main simulation loop, the system enters an IPC (Inter-Process Communication) loop when --no-wait is not specified. The ParallelIPCHandler.process_commands coroutine polls a directory for JSON command files containing instructions such as "interview" or "batch interview", executing them asynchronously against the live OASIS environment.

Summary

  • MiroFish leverages Python's asyncio framework to execute long-running Twitter and Reddit simulations without blocking the interpreter.
  • A global _shutdown_event coordinates graceful termination across all concurrent coroutines when SIGINT or SIGTERM signals are received.
  • The --max-rounds CLI parameter provides deterministic execution limits for testing and CI environments.
  • asyncio.gather() enables parallel execution of platform-specific simulations while maintaining independent logging and database resources.
  • The IPC command loop allows external tools to interact with running simulations via JSON file drops, supporting interview commands and batch operations.

Frequently Asked Questions

How does MiroFish prevent simulations from running indefinitely?

The system implements a round-limiting mechanism through the --max-rounds CLI argument. In backend/scripts/run_parallel_simulation.py (lines 20-24), the total round count derived from the configuration file is truncated to this specified limit, ensuring simulations terminate deterministically for testing or production constraints.

What happens when I press Ctrl+C during a simulation?

Pressing Ctrl+C sends a SIGINT signal that triggers the setup_signal_handlers function (lines 63-72). This sets the global _shutdown_event, which causes all running coroutines to exit their main loops cleanly. The system then awaits environment closure via await env.close() before terminating, preventing data corruption in the SQLite trace databases.

Can I run Twitter and Reddit simulations simultaneously?

Yes. When neither --twitter-only nor --reddit-only flags are provided, the main function uses asyncio.gather() (lines 84-88) to launch both run_twitter_simulation and run_reddit_simulation concurrently. Each platform operates with independent loggers and SQLite databases while sharing the global shutdown event for coordinated termination.

How do external tools interact with a running simulation after it completes the main loop?

When the --no-wait flag is omitted, the system enters an IPC (Inter-Process Communication) loop via ParallelIPCHandler.process_commands. This coroutine monitors a designated directory for JSON command files containing instructions such as "interview" or "batch interview". Upon detecting a valid command, it executes the operation asynchronously against the live OASIS environment and writes responses to an output directory, enabling external orchestration without restarting the simulation infrastructure.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →