This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 482e770d97f7e2af8c88cdf0154bd3e5acde9413 Author: Benoit Tellier <[email protected]> AuthorDate: Sun Jun 27 12:20:12 2021 +0700 [PERFORMANCE] Fasten Mailbox/get by ids - Load quotas only once Was loaded for each id... - Shortcut on emtpy Ids This happens for instance when chaining /changes and /get with backreference. We can save on subscriptions / quota loading... --- .../org/apache/james/jmap/mail/MailboxGet.scala | 4 +++ .../james/jmap/method/MailboxGetMethod.scala | 34 +++++++++++++--------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxGet.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxGet.scala index af866cd..2666989 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxGet.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxGet.scala @@ -47,6 +47,10 @@ object MailboxGet { case class UnparsedMailboxId(id: Id) +object Ids { + val EMPTY = Ids(List()) +} + case class Ids(value: List[UnparsedMailboxId]) case class MailboxGetRequest(accountId: AccountId, diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala index ca9b2e1..9a62ca9 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala @@ -28,7 +28,7 @@ import org.apache.james.jmap.core.Invocation.{Arguments, MethodName} import org.apache.james.jmap.core.{AccountId, CapabilityIdentifier, ErrorCode, Invocation, Properties, UuidState} import org.apache.james.jmap.http.MailboxesProvisioner import org.apache.james.jmap.json.{MailboxSerializer, ResponseSerializer} -import org.apache.james.jmap.mail.{Mailbox, MailboxFactory, MailboxGet, MailboxGetRequest, MailboxGetResponse, NotFound, PersonalNamespace, Subscriptions, UnparsedMailboxId} +import org.apache.james.jmap.mail.{Ids, Mailbox, MailboxFactory, MailboxGet, MailboxGetRequest, MailboxGetResponse, NotFound, PersonalNamespace, Subscriptions, UnparsedMailboxId} import org.apache.james.jmap.routes.SessionSupplier import org.apache.james.jmap.utils.quotas.{QuotaLoaderWithPreloadedDefault, QuotaLoaderWithPreloadedDefaultFactory} import org.apache.james.mailbox.exception.MailboxNotFoundException @@ -115,13 +115,19 @@ class MailboxGetMethod @Inject() (serializer: MailboxSerializer, mailboxGetRequest.ids match { case None => getAllMailboxes(capabilities, mailboxSession) .map(MailboxGetResults.found) + case Some(Ids.EMPTY) => SFlux.empty case Some(ids) => - retrieveSubscriptions(mailboxSession) - .flatMapMany(subscriptions => SFlux.fromIterable(ids.value) - .flatMap(id => Try(mailboxIdFactory.fromString(id.id)) - .fold(e => SMono.just(MailboxGetResults.notFound(id)), - mailboxId => getMailboxResultById(capabilities, mailboxId, subscriptions, mailboxSession)), - maxConcurrency = 5)) + SMono.zip(array => (array(0).asInstanceOf[QuotaLoaderWithPreloadedDefault], + array(1).asInstanceOf[Subscriptions]), + quotaFactory.loadFor(mailboxSession), + retrieveSubscriptions(mailboxSession)) + .flatMapMany { + case (quotaLoader, subscriptions) => SFlux.fromIterable(ids.value) + .flatMap(id => Try(mailboxIdFactory.fromString(id.id)) + .fold(e => SMono.just(MailboxGetResults.notFound(id)), + mailboxId => getMailboxResultById(capabilities, mailboxId, subscriptions, quotaLoader, mailboxSession)), + maxConcurrency = 5) + } }) private def retrieveSubscriptions(mailboxSession: MailboxSession): SMono[Subscriptions] = @@ -132,14 +138,14 @@ class MailboxGetMethod @Inject() (serializer: MailboxSerializer, private def getMailboxResultById(capabilities: Set[CapabilityIdentifier], mailboxId: MailboxId, subscriptions: Subscriptions, + quotaLoader: QuotaLoaderWithPreloadedDefault, mailboxSession: MailboxSession): SMono[MailboxGetResults] = - quotaFactory.loadFor(mailboxSession) - .flatMap(quotaLoader => mailboxFactory.create(mailboxId, mailboxSession, quotaLoader, subscriptions) - .map(mailbox => filterShared(capabilities, mailbox)) - .onErrorResume { - case _: MailboxNotFoundException => SMono.just(MailboxGetResults.notFound(mailboxId)) - case error => SMono.error(error) - }) + mailboxFactory.create(mailboxId, mailboxSession, quotaLoader, subscriptions) + .map(mailbox => filterShared(capabilities, mailbox)) + .onErrorResume { + case _: MailboxNotFoundException => SMono.just(MailboxGetResults.notFound(mailboxId)) + case error => SMono.error(error) + } .subscribeOn(Schedulers.elastic) private def filterShared(capabilities: Set[CapabilityIdentifier], mailbox: Mailbox): MailboxGetResults = { --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
