From 64966ea827c2c69d47d159964eedfb08f5e0b606 Mon Sep 17 00:00:00 2001 From: dankito Date: Wed, 27 Nov 2024 03:47:51 +0100 Subject: [PATCH] Added FetchProfile to speed up fetch process --- .../codinux/invoicing/email/EmailsFetcher.kt | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/EmailsFetcher.kt b/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/EmailsFetcher.kt index 98767d1..1b102e7 100644 --- a/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/EmailsFetcher.kt +++ b/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/EmailsFetcher.kt @@ -1,12 +1,6 @@ package net.codinux.invoicing.email -import jakarta.mail.Folder -import jakarta.mail.Message -import jakarta.mail.Multipart -import jakarta.mail.Part -import jakarta.mail.Session -import jakarta.mail.Store -import jakarta.mail.UIDFolder +import jakarta.mail.* import jakarta.mail.event.MessageCountAdapter import jakarta.mail.event.MessageCountEvent import kotlinx.coroutines.* @@ -117,9 +111,14 @@ open class EmailsFetcher( return@runBlocking emptyList() } - val startUid = max(status.options.lastRetrievedMessageId?.let { it + 1 } ?: 0, 1) // message numbers start at 1 + val startUid = (status.options.lastRetrievedMessageId ?: 0) + 1 // message numbers start at 1 + val messages = folder.getMessagesByUID(startUid, UIDFolder.MAXUID) - folder.getMessagesByUID(startUid, UIDFolder.MAXUID).mapNotNull { message -> + // for each data type like envelope (from, subject, ...), body structure, if message is unread, ... a network request is + // executed, making the overall process very slow -> use FetchProfile to prefetch requested data with a single request + folder.fetch(messages, getFetchProfile(status)) + + messages.mapNotNull { message -> async(coroutineDispatcher) { try { getEmail(message, status) @@ -134,6 +133,15 @@ open class EmailsFetcher( .filterNotNull() } + private fun getFetchProfile(status: FetchEmailsStatus) = FetchProfile().apply { + add(UIDFolder.FetchProfileItem.UID) // message UID + add(FetchProfile.Item.ENVELOPE) // from, subject, to, ... + add(FetchProfile.Item.CONTENT_INFO) // content type, disposition, ... + + // add(FetchProfile.Item.FLAGS) // message status like unread, deleted, draft, ... + // add(IMAPFolder.FetchProfileItem.MESSAGE) // the entire message including all attachments, headers, ... there should be rarely a use case for it + } + protected open fun getEmail(message: Message, status: FetchEmailsStatus): Email? { val parts = getAllMessageParts(message) val messageBodyParts = parts.filter { it.part.fileName == null && it.mediaType in MessageBodyMediaTypes }