async def METHOD_NAME(self):
    interval = self.expire * 4
    await asyncio.sleep(interval)
    while not self.event_stream_stop_event.is_set():
        # since we interrupt the cleanup loop after every queue, there's
        # a chance the self.queues dict is modified during iteration.
        # so, we first make a copy of all the items of the dict and any
        # new queues will be processed on the next loop through
        queue_items = [i for i in self.queues.items()]
        for key, q in queue_items:
            if q.empty():
                continue
            items = []
            num_dropped = 0
            while not q.empty():
                item = q.get_nowait()
                q.task_done()
                if not item:
                    # exit signal received
                    return
                if item.expired:
                    num_dropped += 1
                    continue
                items.append(item)
            for item in items:
                q.put_nowait(item)
            if num_dropped > 0:
                logger.debug(f"Cleaned {num_dropped} events from queue {key}")
            # cleanup is not urgent, so give other tasks a chance
            await asyncio.sleep(0.1)
        await asyncio.sleep(interval)