diff options
author | Kali Kaneko <kali@leap.se> | 2016-03-23 17:50:21 -0400 |
---|---|---|
committer | Kali Kaneko <kali@leap.se> | 2016-03-24 14:00:12 -0400 |
commit | 49ba2965434c6f771e7946899901c594beed8908 (patch) | |
tree | 3a7fbc3831f31d692d2ec417381d2cbc091faca9 /src | |
parent | 7c9082152155100b171450f54c56c614104175df (diff) |
[bug] let the inbox used in IncomingMail notify any subscribed Mailbox
the mail service uses an Account object created from scratch, so it
wasn't sharing the collections mapping with the other Account object
that is created in the IMAP Service.
I make it a class attribute to allow mailbox notifications.
However, with the transition to a single service tree, this class
attribute can again become a class instance.
This is somehow related to a PR proposed recently by cz8s in pixelated
team:
https://github.com/leapcode/leap_mail/pull/228
However, I'm reluctant to re-use IMAPMailbox instances, since they
represent concurrent views over the same collection. I believe that
sharing the same underlying collection might be enough.
Diffstat (limited to 'src')
-rw-r--r-- | src/leap/mail/mail.py | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/src/leap/mail/mail.py b/src/leap/mail/mail.py index c0e16a6..b9c97f6 100644 --- a/src/leap/mail/mail.py +++ b/src/leap/mail/mail.py @@ -29,6 +29,8 @@ import StringIO import time import weakref +from collections import defaultdict + from twisted.internet import defer from twisted.python import log @@ -924,19 +926,25 @@ class Account(object): adaptor_class = SoledadMailAdaptor + # this is a defaultdict, indexed by userid, that returns a + # WeakValueDictionary mapping to collection instances so that we always + # return a reference to them instead of creating new ones. however, + # being a dictionary of weakrefs values, they automagically vanish + # from the dict when no hard refs is left to them (so they can be + # garbage collected) this is important because the different wrappers + # rely on several kinds of deferredlocks that are kept as class or + # instance variables. + + # We need it to be a class property because we create more than one Account + # object in the current usage pattern (ie, one in the mail service, and + # another one in the IncomingMailService). When we move to a proper service + # tree we can let it be an instance attribute. + _collection_mapping = defaultdict(weakref.WeakValueDictionary) + def __init__(self, store, ready_cb=None): self.store = store self.adaptor = self.adaptor_class() - # this is a mapping to collection instances so that we always - # return a reference to them instead of creating new ones. however, - # being a dictionary of weakrefs values, they automagically vanish - # from the dict when no hard refs is left to them (so they can be - # garbage collected) this is important because the different wrappers - # rely on several kinds of deferredlocks that are kept as class or - # instance variables - self._collection_mapping = weakref.WeakValueDictionary() - self.mbox_indexer = MailboxIndexer(self.store) # This flag is only used from the imap service for the moment. @@ -1069,7 +1077,8 @@ class Account(object): :rtype: deferred :return: a deferred that will fire with a MessageCollection """ - collection = self._collection_mapping.get(name, None) + collection = self._collection_mapping[self.store.userid].get( + name, None) if collection: return defer.succeed(collection) @@ -1077,7 +1086,7 @@ class Account(object): def get_collection_for_mailbox(mbox_wrapper): collection = MessageCollection( self.adaptor, self.store, self.mbox_indexer, mbox_wrapper) - self._collection_mapping[name] = collection + self._collection_mapping[self.store.userid][name] = collection return collection d = self.adaptor.get_or_create_mbox(self.store, name) |