Open
Description
If a write fails when pushing an item to the LIFO queue, some data may be actually written before an exception is raised. When trying to pop, the end of the file is supposed to have the size of the last item, but it actually contains whatever was in the partially written data from previous failed push() calls.
>>> from queuelib import LifoDiskQueue
>>> q = LifoDiskQueue("./small_fs/queue") # Filesystem has less than 100KB available.
>>> for i in range(100):
... q.push(b'a' * 1000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "queuelib/queue.py", line 152, in push
self.f.write(string)
IOError: [Errno 28] No space left on device
>>> q.pop()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "queuelib/queue.py", line 162, in pop
self.f.seek(-size-self.SIZE_SIZE, os.SEEK_END)
IOError: [Errno 22] Invalid argument
The error above comes from the value of size
, which is decoded from the last SIZE_SIZE
bytes of the file. When that value is larger than the file itself the seek will fail.