Exemplo n.º 1
0
   def _RemoveContact(contact_to_remove):
       """Insert a 'removed' contact with the same contact_id as the one being removed and then
 delete the actual contact that's being removed."""
       removed_contact = Contact.CreateRemovedContact(
           contact_to_remove.user_id, contact_to_remove.contact_id,
           self._notify_timestamp)
       yield gen.Task(removed_contact.Update, self._client)
       yield Operation.TriggerFailpoint(self._client)
       yield gen.Task(contact_to_remove.Delete, self._client)
Exemplo n.º 2
0
    def _PrepareFetchedContactsForUpdate(self):
        """Process fetched contacts.  Figure out which ones to create/remove/delete/keep.
    On entry, we have three dicts with contacts:
    * All of the contacts that we just fetched: self._fetched_contacts
    * All of the contacts from the same source that are currently persisted: self._existing_contacts_dict.
    * All of the contacts (regardless of source) that are currently persisted: self._all_contacts_dict.
    The existing_contacts_dict contains contacts that are either present or in the 'removed' state.
    Two lists are consumed by the update phase after this phase is complete:
    * self._create_delete_contacts: tuples of insert/delete contacts pairs.
    * self._contacts_to_delete: contacts to be deleted.
    """
        contacts_to_unremove = [
        ]  # Are currently 'removed' and will now be present.
        contacts_to_create = []  # Currently unknown but will now be present.
        # Create a dict of all present contacts and then while iterating, remove fetched contacts so that the remaining
        #   contacts will be the ones that have been removed from the contact source since the last fetch operation.
        contacts_to_remove = {
            c.contact_id: c
            for c in self._existing_contacts_dict.itervalues()
            if not c.IsRemoved()
        }
        for fetched_contact in self._fetched_contacts.itervalues():
            existing_contact = self._existing_contacts_dict.get(
                fetched_contact.contact_id, None)
            if existing_contact is None:
                # We don't know anything about this contact_id, so we'll create a contact.
                contacts_to_create.append(fetched_contact)
            else:
                if existing_contact.IsRemoved():
                    # Currently this contact is in a removed state, but the contact source now says it's present
                    #   so add it to un-remove list.  A new contact will be created the the 'removed' contact will be deleted.
                    contacts_to_unremove.append(fetched_contact)
                else:
                    # This existing contact is also present in fetched contacts, so remove it from removed dict.  After
                    #   we're done iterating over all the fetched contacts, this dict will contain all currently existing
                    #   contacts which should be removed because the fetched contacts source no longer contains it.
                    contacts_to_remove.pop(fetched_contact.contact_id, None)

        # Determine if the contacts being removed should trigger a removed contacts reset.
        if self._all_removed_contacts_count + len(
                contacts_to_remove) >= Contact.MAX_REMOVED_CONTACTS_LIMIT:
            self._removed_contacts_reset = True

        # Get self._create_delete_contacts into desired state for update phase.
        for contact in contacts_to_remove.itervalues():
            if self._removed_contacts_reset:
                # Don't create any removed contacts if we decided to do a removed contacts reset.
                removed_contact = None
            else:
                removed_contact = Contact.CreateRemovedContact(
                    self._user_id, contact.contact_id, self._notify_timestamp)
            self._create_delete_contacts.append((removed_contact, contact))
            assert not contact.IsRemoved(), contact
            self._all_present_contacts_count -= 1
        for contact in contacts_to_unremove:
            delete_contact = self._existing_contacts_dict[contact.contact_id]
            assert delete_contact.IsRemoved(), delete_contact
            if self._all_present_contacts_count < Contact.MAX_CONTACTS_LIMIT:
                self._create_delete_contacts.append((contact, delete_contact))
                self._all_present_contacts_count += 1
            else:
                # This contact will remain in the 'removed' state.
                self._skipped_contact_create_count += 1
        for contact in contacts_to_create:
            if self._all_present_contacts_count < Contact.MAX_CONTACTS_LIMIT:
                self._create_delete_contacts.append((contact, None))
                self._all_present_contacts_count += 1
            else:
                # This just won't get created.
                self._skipped_contact_create_count += 1
        if self._removed_contacts_reset:
            for contact in self._all_contacts_dict.itervalues():
                if contact.IsRemoved():
                    self._contacts_to_delete.append(contact)

        if self._skipped_contact_create_count > 0:
            logging.warning(
                'Skipped creation of %d fetched contacts due to max contact limit'
                % self._skipped_contact_create_count)