QueuePool overflow handling not threadsafe

Issue #608 resolved
jek created an issue

The {{{QueuePool}}}'s "can I overflow?" logic is not threadsafe and can fairly easily exceed the max_overflow cap under load.

Comments (6)

  1. Mike Bayer repo owner

    this is true, and for this reason I am planning on not advising the usage of QueuePool as a throttle for database connections (the database should do that). feel free to come up with ideas here, but my impression is that to mutex "efficiently" would probably mean removing the usage of Queue.Queue altogether (otherwise we are mutexing mutexes) and essentially rewriting the whole thing.

    from the book:

    Note that, at the time of this writing, the overflow logic in QueuePool is “soft”; that is, while the queue implementation is strongly thread-synchronized and guarantees a fixed ceiling on the number of checked-in connections that will remain open, the overflow itself is not synchronized and is susceptible, in extremely rare circumstances, to surpassing max_overflow if a tremendous number of threads simultaneously hammer it. This event does not threaten the state integrity of QueuePool, which will return to normal as the connections are returned. But for this reason, QueuePool should not be relied upon for database load “throttling” in extremely high load environments.

  2. jek reporter
    • changed milestone to 0.4.0

    There's a mutex thrown around the overflow logic in changeset:2737 that enforces max_overflow.

    Because the mutexes of the main pool and overflow are disjoint, a "full" will still be raised if overflow if full and a slot opens up in the pool while we're thinking about overflow. I'm fine with that- the implementation is simple and the important part is not exceeding the max cap, the race seems harmless.

    If you agree, I think we can close this and start re-writing the book. :)

  3. Mike Bayer repo owner

    lets add the test case here as a unit test, either within test/engine/pool.py or separately.

  4. Log in to comment