summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se>2016-03-23 17:50:21 -0400
committerKali Kaneko <kali@leap.se>2016-03-24 14:00:12 -0400
commit49ba2965434c6f771e7946899901c594beed8908 (patch)
tree3a7fbc3831f31d692d2ec417381d2cbc091faca9
parent7c9082152155100b171450f54c56c614104175df (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.
-rw-r--r--src/leap/mail/mail.py31
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)