question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

queue length for SQLiteQueue is incorrect when running in multiple processes

See original GitHub issue

Possibly expected behavior, but I think it’s worth reporting, because the queue looks usable otherwise.

The queue size is set only once on queue creation. self.total = self._count(), so if we have a producer in 1 process and a consumer in another process, we end up with size in the negatives.

To reproduce, we need producer and a consumer that’s faster than the producer.

# producer process
import persistqueue as Q; q = Q.SQLiteQueue('queue', multithreading=True)
while True: q.put('hi'); time.sleep(0.01)
# consumer process
import persistqueue as Q; q = Q.SQLiteQueue('queue', auto_commit=False, multithreading=True)


while True:
    try:
        q.qsize(), q.get(block=False); q.task_done()
    except persistqueue.exceptions.Empty:
        pass

Calling q._count() returns the correct size, because it hits the DB, of course.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
decaturcommented, May 28, 2021

Yes, this seems to be a bug. So instead of

    while not queue.empty():
        item = queue.get()
        pprint(item)
        queue.task_done()

use the workaround

    while True:
        try:
            item = queue.get(block=False)
        except persistqueue.exceptions.Empty:
            break
        pprint(item)
        queue.task_done()
0reactions
imidoriyacommented, Apr 9, 2021

Recent updates have added max(0, count) to remove a negative qsize(). That doesn’t change the overall issue, but prevents impossible size results. On the Ack Queues, a new active_size() was added which includes the nack cache. It may be anecdotal, but I believe this has produced a more accurate return in my multi-threaded environment as it’s calculating when an item is put/ack/ack_failed, and not on put/get/nack. But that’s more of a decision on when you think the queue size should be decremented, on get or on completion.

Read more comments on GitHub >

github_iconTop Results From Across the Web

queue length for SQLiteQueue is incorrect when running in multiple ...
The queue size is set only once on queue creation. self.total = self._count() , so if we have a producer in 1 process...
Read more >
Optimize/correct behaviour of a combination of Python ...
Your Queue has multiple consumers running simultaneously, the empty() function will sometimes return False but another Process happens to ...
Read more >
persist-queue - PyPI
A thread-safe disk based persistent queue in Python. ... ack_failed: there might be something wrong during process, so just mark item as failed....
Read more >
multiprocessing — Process-based parallelism — Python 3.11 ...
Note that data in a pipe may become corrupted if two processes (or threads) try ... Otherwise (block is False ), put an...
Read more >
Multiprocessing Queue in Python
Python provides a number of process-safe queues, ... Once a size limited queue is full, new items cannot be added and calls to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found