Make TimeoutQueue.iter() actually expire items

It is functionally fine not to, but causes objects to never be freed
if iter() is the only method called on the queue (ie. no
enqueue/dequeue, len(), ...)
This commit is contained in:
Valentin Lorentz 2022-10-24 23:43:50 +02:00
parent 2c5dc405fc
commit 009b900100
2 changed files with 31 additions and 3 deletions

View File

@ -1,6 +1,6 @@
###
# Copyright (c) 2002-2009, Jeremiah Fincher
# Copyright (c) 2010-2021, Valentin Lorentz
# Copyright (c) 2010-2022, Valentin Lorentz
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@ -349,7 +349,10 @@ class TimeoutQueue(object):
return self.queue.dequeue()[1]
def __iter__(self):
# We could _clearOldElements here, but what happens if someone stores
self._clearOldElements()
# You may think re-checking _getTimeout() after we just called
# _clearOldElements is redundant, but what happens if someone stores
# the resulting generator and elements that should've timed out are
# yielded? Hmm? What happens then, smarty-pants?
for (t, elt) in self.queue:

View File

@ -1,7 +1,7 @@
###
# Copyright (c) 2002-2005, Jeremiah Fincher
# Copyright (c) 2009,2011, James McCoy
# Copyright (c) 2010-2021, Valentin Lorentz
# Copyright (c) 2010-2022, Valentin Lorentz
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@ -1182,6 +1182,31 @@ class TestTimeoutQueue(SupyTestCase):
q.reset()
self.assertFalse(1 in q)
def testClean(self):
def iter_and_next(q):
next(iter(q))
def contains(q):
42 in q
for f in (len, repr, list, iter_and_next, contains):
print(f)
with self.subTest(f=f.__name__):
q = TimeoutQueue(1)
q.enqueue(1)
timeFastForward(0.5)
q.enqueue(2)
self.assertEqual([x for (_, x) in q.queue], [1, 2])
f(q)
self.assertEqual([x for (_, x) in q.queue], [1, 2])
timeFastForward(0.6)
self.assertEqual([x for (_, x) in q.queue], [1, 2]) # not cleaned yet
f(q)
self.assertEqual([x for (_, x) in q.queue], [2]) # now it is
class TestCacheDict(SupyTestCase):
def testMaxNeverExceeded(self):
max = 10