coleifer / peewee

a small, expressive orm -- supports postgresql, mysql, sqlite and cockroachdb
http://docs.peewee-orm.com/
MIT License
11.06k stars 1.37k forks source link

SqliteQueueDatabase pause(), unpause() do not block the caller #2877

Closed travnick closed 4 months ago

travnick commented 4 months ago

documentation says that:

For cases when you wish to temporarily write to the database from a different thread, you can use the pause() and unpause() methods. These methods block the caller until the writer thread is finished with its current workload

But these methods do not block:

    def pause(self):
        with self._lock: # or lock deveted in new code
            self._write_queue.put(PAUSE)

    def unpause(self):
        with self._lock: # or lock deveted in new code
            self._write_queue.put(UNPAUSE)

Queue.put only waits for the space in queue. So this will block only if the queue is full.

I guess Condition Object or Event will do the job here.

coleifer commented 4 months ago

Yes you're right, let me look into it!

travnick commented 4 months ago

Looks like fixed, but not in every case:

coleifer commented 4 months ago

You’re correct. Let me look into it, it may be that we just get rid of pause and unpause.

travnick commented 4 months ago

removing pause/unpause does not fix the other "waiting forever" issue and executing outdated queries - stop() feels like: stop execution, and abort any scheduled task (query here).

coleifer commented 4 months ago

I think this may address the issue, thanks for the suggestion about aborting everything. Now when the queue is stopped, we'll drain the queue and unblock any waiters (queries will get a ShutdownException, pause/unpause will just unblock). 519a84e57aa9ff994ddbf1b605b700426d8b3d79

travnick commented 4 months ago

As far as I can see, there are more issues left when Writer thread is stopped:

In my opinion, write_queue and _is_stopped belongs to Writer state itself - managing them outside the Writer breaks single responsibility principle and is quite error-prone because introduces multiple places to manage them, instead of having only one inside the Writer.

Sorry for not providing all review results at once, but it's not easy to analyse each case without knowing the project internals and with threads on board.

coleifer commented 4 months ago

Thank you I’ll take a look. I’m grateful for the feedback and appreciate you taking the time. This particular module was just thrown together, and it clearly had some issues.