Pull loop one level up
This commit is contained in:
parent
b6e0be701e
commit
fd85b167ec
|
@ -19,7 +19,7 @@ from twisted.internet import defer, reactor
|
||||||
from synapse.events import FrozenEvent, USE_FROZEN_DICTS
|
from synapse.events import FrozenEvent, USE_FROZEN_DICTS
|
||||||
from synapse.events.utils import prune_event
|
from synapse.events.utils import prune_event
|
||||||
|
|
||||||
from synapse.util.async import ObservableDeferred
|
from synapse.util.async import ObservableDeferred, run_on_reactor
|
||||||
from synapse.util.logcontext import preserve_fn, PreserveLoggingContext
|
from synapse.util.logcontext import preserve_fn, PreserveLoggingContext
|
||||||
from synapse.util.logutils import log_function
|
from synapse.util.logutils import log_function
|
||||||
from synapse.api.constants import EventTypes
|
from synapse.api.constants import EventTypes
|
||||||
|
@ -89,12 +89,14 @@ class _EventPeristenceQueue(object):
|
||||||
|
|
||||||
return deferred.observe()
|
return deferred.observe()
|
||||||
|
|
||||||
def handle_queue(self, room_id, callback):
|
def handle_queue(self, room_id, per_item_callback):
|
||||||
"""Attempts to handle the queue for a room if not already being handled.
|
"""Attempts to handle the queue for a room if not already being handled.
|
||||||
|
|
||||||
The given callback will be invoked with a 'queue' arg, which is a
|
The given callback will be invoked with for each item in the queue,1
|
||||||
generator over _EventPersistQueueItem's. The queue will finish if there
|
of type _EventPersistQueueItem. The per_item_callback will continuously
|
||||||
are no longer any items in the room queue.
|
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
|
This function should therefore be called whenever anything is added
|
||||||
to the queue.
|
to the queue.
|
||||||
|
@ -108,15 +110,26 @@ class _EventPeristenceQueue(object):
|
||||||
|
|
||||||
self._currently_persisting_rooms.add(room_id)
|
self._currently_persisting_rooms.add(room_id)
|
||||||
|
|
||||||
try:
|
@defer.inlineCallbacks
|
||||||
callback(self._get_drainining_queue(room_id))
|
def handle_queue_loop():
|
||||||
finally:
|
try:
|
||||||
self._currently_persisting_rooms.discard(room_id)
|
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)()
|
||||||
|
|
||||||
def _get_drainining_queue(self, room_id):
|
def _get_drainining_queue(self, room_id):
|
||||||
queue = self._event_persist_queues.pop(room_id, None)
|
queue = self._event_persist_queues.setdefault(room_id, deque())
|
||||||
if not queue:
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
|
@ -180,30 +193,22 @@ class EventsStore(SQLBaseStore):
|
||||||
|
|
||||||
def _maybe_start_persisting(self, room_id):
|
def _maybe_start_persisting(self, room_id):
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def persisting_queue(queue):
|
def persisting_queue(item):
|
||||||
for item in queue:
|
if item.current_state:
|
||||||
try:
|
for event, context in item.events_and_contexts:
|
||||||
ret = None
|
# There should only ever be one item in
|
||||||
if item.current_state:
|
# events_and_contexts when current_state is
|
||||||
for event, context in item.events_and_contexts:
|
# not None
|
||||||
# There should only ever be one item in
|
yield self._persist_event(
|
||||||
# events_and_contexts when current_state is
|
event, context,
|
||||||
# not None
|
current_state=item.current_state,
|
||||||
yield self._persist_event(
|
backfilled=item.backfilled,
|
||||||
event, context,
|
)
|
||||||
current_state=item.current_state,
|
else:
|
||||||
backfilled=item.backfilled,
|
yield self._persist_events(
|
||||||
)
|
item.events_and_contexts,
|
||||||
else:
|
backfilled=item.backfilled,
|
||||||
yield self._persist_events(
|
)
|
||||||
item.events_and_contexts,
|
|
||||||
backfilled=item.backfilled,
|
|
||||||
)
|
|
||||||
logger.info("Resolving with ret: %r", ret)
|
|
||||||
item.deferred.callback(ret)
|
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Failed to persist events")
|
|
||||||
item.deferred.errback(e)
|
|
||||||
|
|
||||||
self._event_persist_queue.handle_queue(room_id, persisting_queue)
|
self._event_persist_queue.handle_queue(room_id, persisting_queue)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue