Katkat

Design a lazy-initialized connection pool

AirtableSoftware Engineer · HR Screen

Last updated

Design a thread-safe, lazily initialized connection pool with a PooledConnection wrapper: reuse idle connections first, cap active connections, define exhaustion (block-with-timeout) and shutdown semantics, and analyze concurrency safety and complexity. A common Airtable software-engineering screen question.

Question

Design and implement a thread-safe, lazily initialized connection pool.

You are given an immutable base class Connection (you cannot modify it) that exposes query() and close(). Implement two classes:

  1. ConnectionPool with __init__(maxConnectionNum), getConnection() -> PooledConnection, and close().
  2. PooledConnection with __init__(parent: ConnectionPool, connection: Connection), query(), and close().

Requirements:

  1. Lazy initialization — do not create any Connection in the pool's constructor. Only create a new Connection instance when getConnection() is actually called.
  2. Reuse idle first — when getConnection() is called, hand back an idle (already-created, returned) connection if one exists. Only create a new Connection when no idle connection is available and the number of active connections is below maxConnectionNum.
  3. Cap active connections — the total number of underlying connections (in-use + idle) must never exceed maxConnectionNum.
  4. Exhaustion behavior — define and implement what happens when the pool is exhausted (no idle connection and the cap is reached): block with a timeout, then raise an error on timeout (or block indefinitely if no timeout is configured).
  5. Return semantics — PooledConnection.close() must return the underlying connection to the pool for reuse rather than actually closing it. ConnectionPool.close() must close all underlying connections and reject any further operations.
  6. PooledConnection.query() — delegate to the underlying connection's query(), while guarding against use after the wrapper has been returned/closed.
  7. Concurrency safety — discuss and implement how to make the pool safe for concurrent callers: which synchronization primitives to use, and how to avoid double-return and connection leaks.
  8. Complexity — describe the core data structures and analyze the time/space complexity of getConnection() and close().