diff options
Diffstat (limited to 'client/src/leap/soledad')
-rw-r--r-- | client/src/leap/soledad/client/api.py | 20 | ||||
-rw-r--r-- | client/src/leap/soledad/client/sqlcipher.py | 8 |
2 files changed, 19 insertions, 9 deletions
diff --git a/client/src/leap/soledad/client/api.py b/client/src/leap/soledad/client/api.py index 9000029f..633c07d0 100644 --- a/client/src/leap/soledad/client/api.py +++ b/client/src/leap/soledad/client/api.py @@ -41,13 +41,14 @@ except ImportError: from itertools import chain from StringIO import StringIO +from collections import defaultdict from u1db.remote import http_client from u1db.remote.ssl_match_hostname import match_hostname from zope.interface import implements from leap.common.config import get_path_prefix from leap.common.plugins import collect_plugins -from twisted.internet import defer +from twisted.internet.defer import DeferredLock from leap.soledad.common import SHARED_DB_NAME from leap.soledad.common import soledad_assert @@ -114,6 +115,7 @@ class Soledad(object): local_db_file_name = 'soledad.u1db' secrets_file_name = "soledad.json" default_prefix = os.path.join(get_path_prefix(), 'leap', 'soledad') + _syncing_lock = defaultdict(DeferredLock) def __init__(self, uuid, passphrase, secrets_path, local_db_path, server_url, cert_file, shared_db=None, @@ -200,7 +202,6 @@ class Soledad(object): self._crypto = SoledadCrypto(self._secrets.remote_storage_secret) self._init_u1db_sqlcipher_backend() - self.sync_lock = defer.DeferredLock() if syncable: self._init_u1db_syncer() @@ -671,7 +672,7 @@ class Soledad(object): # ----------------------------------------------------------------- sync_url = urlparse.urljoin(self._server_url, 'user-%s' % self.uuid) - d = self.sync_lock.run(lambda: self._dbsyncer.sync( + d = self.syncing_lock.run(lambda: self._dbsyncer.sync( sync_url, creds=self._creds, defer_decryption=defer_decryption)) @@ -706,6 +707,17 @@ class Soledad(object): return d @property + def syncing_lock(self): + """ + Class based lock to ensure consistency on concurrent calls to sync. + Each lock is based on the path of db file. + + :return: DeferredLock based on this instance path of db file + :rtype: DeferredLock + """ + return self._syncing_lock[self._local_db_path] + + @property def syncing(self): """ Return wether Soledad is currently synchronizing with the server. @@ -713,7 +725,7 @@ class Soledad(object): :return: Wether Soledad is currently synchronizing with the server. :rtype: bool """ - return self.sync_lock.locked + return self.syncing_lock.locked def _set_token(self, token): """ diff --git a/client/src/leap/soledad/client/sqlcipher.py b/client/src/leap/soledad/client/sqlcipher.py index 249ffb1a..6a4fa01a 100644 --- a/client/src/leap/soledad/client/sqlcipher.py +++ b/client/src/leap/soledad/client/sqlcipher.py @@ -420,11 +420,6 @@ class SQLCipherU1DBSync(SQLCipherDatabase): """ ENCRYPT_LOOP_PERIOD = 1 - """ - A dictionary that hold locks which avoid multiple sync attempts from the - same database replica. - """ - def __init__(self, opts, soledad_crypto, replica_uid, cert_file, defer_encryption=False, sync_db=None, sync_enc_pool=None): @@ -513,6 +508,9 @@ class SQLCipherU1DBSync(SQLCipherDatabase): changes, we should add a thread-safe condition to ensure the db is ready before using it. + This method is atomic, with atomicity guaranteed by caller. Each + caller should implement a locking mechanism to ensure atomicity. + :param url: The url of the target replica to sync with. :type url: str :param creds: optional dictionary giving credentials to authorize the |