'Process a PDU received via a federation /send/ transaction, or
via backfill of missing prev_events
Args:
origin (str): server which initiated the /send/ transaction. Will
be used to fetch missing events or state.
pdu (FrozenEvent): received PDU
get_missing (bool): True if we should fetch missing prev_events
Returns (Deferred): completes with None'

@defer.inlineCallbacks
@log_function
def on_receive_pdu(self, origin, pdu, get_missing=True):

    existing = (yield self.get_persisted_pdu(origin, pdu.event_id, do_auth=False))
    already_seen = (existing and ((not existing.internal_metadata.is_outlier()) or pdu.internal_metadata.is_outlier()))
    if already_seen:
        logger.debug('Already    seen    pdu    %s', pdu.event_id)
        return
    if (pdu.room_id in self.room_queues):
        logger.info('Ignoring    PDU    %s    for    room    %s    from    %s    for    now;    join    in    progress', pdu.event_id, pdu.room_id, origin)
        self.room_queues[pdu.room_id].append((pdu, origin))
        return
    state = None
    auth_chain = []
    have_seen = (yield self.store.have_events([ev for (ev, _) in pdu.prev_events]))
    fetch_state = False
    if (not pdu.internal_metadata.is_outlier()):
        min_depth = (yield self.get_min_depth_for_context(pdu.room_id))
        logger.debug('_handle_new_pdu    min_depth    for    %s:    %d', pdu.room_id, min_depth)
        prevs = {e_id for (e_id, _) in pdu.prev_events}
        seen = set(have_seen.keys())
        if (min_depth and (pdu.depth < min_depth)):
            pdu.internal_metadata.outlier = True
        elif (min_depth and (pdu.depth > min_depth)):
            if (get_missing and (prevs - seen)):
                logger.info('Acquiring    lock    for    room    %r    to    fetch    %d    missing    events:    %r...', pdu.room_id, len((prevs - seen)), list((prevs - seen))[:5])
                with (yield self._room_pdu_linearizer.queue(pdu.room_id)):
                    logger.info('Acquired    lock    for    room    %r    to    fetch    %d    missing    events', pdu.room_id, len((prevs - seen)))
                    (yield self._get_missing_events_for_pdu(origin, pdu, prevs, min_depth))
                    have_seen = (yield self.store.have_events(prevs))
                    seen = set(have_seen.iterkeys())
                    if (not (prevs - seen)):
                        logger.info('Found    all    missing    prev    events    for    %s', pdu.event_id)
            elif (prevs - seen):
                logger.info('Not    fetching    %d    missing    events    for    room    %r,event    %s:    %r...', len((prevs - seen)), pdu.room_id, pdu.event_id, list((prevs - seen))[:5])
        if (prevs - seen):
            logger.info('Still    missing    %d    events    for    room    %r:    %r...', len((prevs - seen)), pdu.room_id, list((prevs - seen))[:5])
            fetch_state = True
    if fetch_state:
        logger.debug('_handle_new_pdu    getting    state    for    %s', pdu.room_id)
        try:
            (state, auth_chain) = (yield self.replication_layer.get_state_for_room(origin, pdu.room_id, pdu.event_id))
        except:
            logger.exception('Failed    to    get    state    for    event:    %s', pdu.event_id)
    (yield self._process_received_pdu(origin, pdu, state=state, auth_chain=auth_chain))
