@@ -179,6 +179,37 @@ class UnsupportedRedis(Exception):
179
179
pass
180
180
181
181
182
+ class ExpiringCache (collections .defaultdict ):
183
+ def __init__ (self , default , ttl = 60 , * args , ** kw ):
184
+ collections .defaultdict .__init__ (self , default )
185
+ self ._expires = collections .OrderedDict ()
186
+ self .ttl = ttl
187
+
188
+ def __setitem__ (self , k , v ):
189
+ collections .defaultdict .__setitem__ (self , k , v )
190
+ self ._expires [k ] = time .time () + self .ttl
191
+
192
+ def __delitem__ (self , k ):
193
+ try :
194
+ collections .defaultdict .__delitem__ (self , k )
195
+ except KeyError :
196
+ pass
197
+
198
+ def expire (self ):
199
+ expired = []
200
+ for k in self ._expires .keys ():
201
+ if self ._expires [k ] < time .time ():
202
+ expired .append (k )
203
+ else :
204
+ # as this is an OrderedDict, every key after this
205
+ # was inserted *later*, so if _this_ key is *not* expired,
206
+ # the ones after it aren't either (so we can stop iterating)
207
+ break
208
+ for k in expired :
209
+ del self ._expires [k ]
210
+ del self [k ]
211
+
212
+
182
213
class RedisChannelLayer (BaseChannelLayer ):
183
214
"""
184
215
Redis channel layer.
@@ -226,7 +257,7 @@ def __init__(
226
257
# Event loop they are trying to receive on
227
258
self .receive_event_loop = None
228
259
# Buffered messages by process-local channel name
229
- self .receive_buffer = collections . defaultdict (asyncio .Queue )
260
+ self .receive_buffer = ExpiringCache (asyncio .Queue , ttl = self . expiry )
230
261
# Detached channel cleanup tasks
231
262
self .receive_cleaners = []
232
263
# Per-channel cleanup locks to prevent a receive starting and moving
@@ -616,6 +647,7 @@ async def group_discard(self, group, channel):
616
647
key = self ._group_key (group )
617
648
async with self .connection (self .consistent_hash (group )) as connection :
618
649
await connection .zrem (key , channel )
650
+ self .receive_buffer .expire ()
619
651
620
652
async def group_send (self , group , message ):
621
653
"""
0 commit comments