Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion skyrl/tinker/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,9 @@ async def lifespan(app: FastAPI):
"""Lifespan event handler for startup and shutdown."""

db_url = get_async_database_url(app.state.engine_config.database_url)
app.state.db_engine = create_async_engine(db_url, echo=False)
app.state.db_engine = create_async_engine(
db_url, echo=False, pool_size=50, max_overflow=100, pool_timeout=120
)
Comment on lines +236 to +238

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Passing pool_size, max_overflow, and pool_timeout directly to create_async_engine introduces two major issues:

  1. TypeError with In-Memory SQLite: When using an in-memory SQLite database (common in test suites), SQLAlchemy defaults to using StaticPool. StaticPool does not accept these pool configuration arguments, which will cause a TypeError and crash the application on startup.
  2. Database Lock Contention: For file-based SQLite (the default database configuration), a pool size of 50 with 100 overflow (up to 150 connections) is highly discouraged. SQLite only supports a single concurrent writer, and having so many concurrent connections will lead to severe database lock contention (database is locked / SQLITE_BUSY errors), even with WAL mode enabled.

To resolve this, we should conditionally apply these pool parameters only when the database backend is not SQLite (e.g., PostgreSQL).

Suggested change
app.state.db_engine = create_async_engine(
db_url, echo=False, pool_size=50, max_overflow=100, pool_timeout=120
)
engine_kwargs = {"echo": False}
if not db_url.startswith("sqlite"):
engine_kwargs.update(
pool_size=50,
max_overflow=100,
pool_timeout=120,
)
app.state.db_engine = create_async_engine(db_url, **engine_kwargs)

enable_sqlite_wal(app.state.db_engine.sync_engine)

async with app.state.db_engine.begin() as conn:
Expand Down
Loading