'Attempts to handle the queue for a room if not already being handled.
The given callback will be invoked with for each item in the queue,1
of type _EventPersistQueueItem. The per_item_callback will continuously
be called with new items, unless the queue becomnes empty. The return
value of the function will be given to the deferreds waiting on the item,
exceptions will be passed to the deferres as well.
This function should therefore be called whenever anything is added
to the queue.
If another callback is currently handling the queue then it will not be
invoked.'

def handle_queue(self, room_id, per_item_callback):

    if (room_id in self._currently_persisting_rooms):
        return
    self._currently_persisting_rooms.add(room_id)
    @defer.inlineCallbacks
    def handle_queue_loop():
        try:
            queue = self._get_drainining_queue(room_id)
            for item in queue:
                try:
                    ret = (yield per_item_callback(item))
                    item.deferred.callback(ret)
                except Exception as e:
                    item.deferred.errback(e)
        finally:
            queue = self._event_persist_queues.pop(room_id, None)
            if queue:
                self._event_persist_queues[room_id] = queue
            self._currently_persisting_rooms.discard(room_id)
    preserve_fn(handle_queue_loop)()
