Issue: Would thread pool be useful for single thread application?
Author: kamelzcs
State: closed
Created: 2014-12-15 10:25:02

The docs said, `If your application is single-threaded, only one connection will be opened.`
In frameworks like `Tornado`, there is only one thread.
Does it mean, no matter how many requests from the client, there would be ONLY ONE connection to deal with the requests?


I didn't think about Tornado when writing that, to be honest. The connections are stored in a heap on the pooled database instance, so there's no reason why a single-threaded app could not check out multiple connections. There's a catch, though...

The database stores the connection on a threadlocal. So if you had a multi-threaded app, each thread would have it's own connection (which would be managed by the pool). In a single-threaded app using an event-loop, how would peewee know which connection belongs with which callback?


I checked again, and found  single-threaded app could check out multiple connections.

But for things like `transaction`, which stores the info in `threadlocal` variable.
For single thread app, this kind of `transaction` would not work, as all the transactions are within the same `threadlocal`.

Is this one the catch which should be taken care?


> I checked again, and found single-threaded app could check out multiple connections.

Oh really? I would have thought that calling `db.get_conn()` in a single-threaded app would always yield the same connection. Were you using a different API than `get_conn()`?


I just thought the `PooledDatabase _connect()` could create multi connections.
But the `get_conn()` could only get the same connection, I think.

BTW:  The transaction part will not work in single-thread app, isn't it?


> I just thought the PooledDatabase _connect() could create multi connections.
> But the get_conn() could only get the same connection, I think.

Right, the `_connect()` method will create new connections, but that is a private API and will not actually work how you think it will.

The database instance your app uses has a threadlocal (`__local`) that stores the currently active connection (or None if no conn is open yet). Whenever you use a model or the db to execute a query, the db will call `self.get_conn()` to get the connection stored on the threadlocal, creating one if one does not exist.

So while you can open as many connections as you want, the database will only use the one stored on the threadlocal.


I'm closing the issue as this is not really a bug, but if you have more questions or would like to discuss, feel free to continue commenting.


But for single-thread app, this `__local` actually becomes a shared variable.
Then does it mean, things like `transaction(object)`and `get_conn()` which assume the `__local` is private to each client thread, would not work as desired?


> But for single-thread app, this __local actually becomes a shared variable. Then does it mean, things like transaction(object)and get_conn() which assume the __local is private to each client thread, would not work as desired?

Exactly. For a single-threaded application, it acts like an instance attribute, and since there is only a single database instance, there will only be a single connection.


Thanks for your time and great classification.


My pleasure! I hope I've helped, or at least explained the limitations of the code.