Skip to content

Commit

Permalink
chunk
Browse files Browse the repository at this point in the history
  • Loading branch information
squeaky-pl committed Nov 5, 2024
1 parent 8bdde5f commit 0d50046
Showing 1 changed file with 37 additions and 37 deletions.
74 changes: 37 additions & 37 deletions inbox/mailsync/backends/imap/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from inbox.models.session import session_scope
from inbox.models.util import reconcile_message
from inbox.sqlalchemy_ext.util import get_db_api_cursor_with_query
from inbox.util.itert import chunk

log = get_logger()

Expand Down Expand Up @@ -232,7 +233,7 @@ def remove_deleted_uids(account_id: int, folder_id: int, uids: Iterable[int]) ->
case _:
assert_never(category_type)

for uid in uids:
for uid_chunk in chunk(uids, 10):
# We do this one-uid-at-a-time because issuing many deletes within a
# single database transaction is problematic. But loading many
# objects into a session and then frequently calling commit() is also
Expand All @@ -241,53 +242,52 @@ def remove_deleted_uids(account_id: int, folder_id: int, uids: Iterable[int]) ->
# Performance could perhaps be additionally improved by choosing a
# sane balance, e.g., operating on 10 or 100 uids or something at once.
with session_scope(account_id) as db_session:
imapuid = (
imapuids = (
db_session.query(ImapUid)
.filter(
ImapUid.account_id == account_id,
ImapUid.folder_id == folder_id,
ImapUid.msg_uid == uid,
ImapUid.msg_uid.in_(uid_chunk),
)
.with_hint(
ImapUid,
"FORCE INDEX (ix_imapuid_account_id_folder_id_msg_uid_desc)",
)
.options(options)
.one_or_none()
.all()
)
if imapuid is None:
continue
deleted_uid_count += 1
message = imapuid.message

db_session.delete(imapuid)

if message is not None:
message.imapuids.remove(imapuid)

if not message.imapuids and message.is_draft:
# Synchronously delete drafts.
thread = message.thread
if thread is not None:
thread.messages.remove(message)
# Thread.messages relationship is versioned i.e. extra
# logic gets executed on remove call.
# This early flush is needed so the configure_versioning logic
# in inbox.model.sessions can work reliably on newer versions of
# SQLAlchemy.
db_session.flush()
db_session.delete(message)
if thread is not None and not thread.messages:
db_session.delete(thread)
else:
update_message_metadata(
db_session, category_type, message, message.is_draft
)
if not message.imapuids:
# But don't outright delete messages. Just mark them as
# 'deleted' and wait for the asynchronous
# dangling-message-collector to delete them.
message.mark_for_deletion()
for imapuid in imapuids:
deleted_uid_count += 1
message = imapuid.message

db_session.delete(imapuid)

if message is not None:
message.imapuids.remove(imapuid)

if not message.imapuids and message.is_draft:
# Synchronously delete drafts.
thread = message.thread
if thread is not None:
thread.messages.remove(message)
# Thread.messages relationship is versioned i.e. extra
# logic gets executed on remove call.
# This early flush is needed so the configure_versioning logic
# in inbox.model.sessions can work reliably on newer versions of
# SQLAlchemy.
db_session.flush()
db_session.delete(message)
if thread is not None and not thread.messages:
db_session.delete(thread)
else:
update_message_metadata(
db_session, category_type, message, message.is_draft
)
if not message.imapuids:
# But don't outright delete messages. Just mark them as
# 'deleted' and wait for the asynchronous
# dangling-message-collector to delete them.
message.mark_for_deletion()
db_session.commit()
log.info("Deleted expunged UIDs", count=deleted_uid_count)

Expand Down

0 comments on commit 0d50046

Please sign in to comment.