diff options
| -rw-r--r-- | client/src/leap/soledad/client/sqlcipher.py | 69 | ||||
| -rw-r--r-- | client/src/leap/soledad/client/sync.py | 3 | 
2 files changed, 18 insertions, 54 deletions
diff --git a/client/src/leap/soledad/client/sqlcipher.py b/client/src/leap/soledad/client/sqlcipher.py index 18a9c5de..2151884a 100644 --- a/client/src/leap/soledad/client/sqlcipher.py +++ b/client/src/leap/soledad/client/sqlcipher.py @@ -55,8 +55,7 @@ from functools import partial  from pysqlcipher import dbapi2 as sqlcipher_dbapi2  from twisted.internet import reactor -from twisted.internet.threads import deferToThreadPool -from twisted.python.threadpool import ThreadPool +from twisted.internet import defer  from twisted.enterprise import adbapi  from leap.soledad.client.http_target import SoledadHTTPSyncTarget @@ -445,8 +444,6 @@ class SQLCipherU1DBSync(SQLCipherDatabase):          self.received_docs = []          self.running = False -        self._sync_threadpool = None -        self._initialize_sync_threadpool()          self._reactor = reactor          self._reactor.callWhenRunning(self._start) @@ -462,54 +459,27 @@ class SQLCipherU1DBSync(SQLCipherDatabase):      def _start(self):          if not self.running: -            self._sync_threadpool.start()              self.shutdownID = self._reactor.addSystemEventTrigger(                  'during', 'shutdown', self.finalClose)              self.running = True -    def _defer_to_sync_threadpool(self, meth, *args, **kwargs): -        return deferToThreadPool( -            self._reactor, self._sync_threadpool, meth, *args, **kwargs) -      def _initialize_main_db(self): +        self._db_handle = initialize_sqlcipher_db( +            self._opts, check_same_thread=False) +        self._real_replica_uid = None +        self._ensure_schema() +        self.set_document_factory(soledad_doc_factory) -        def _init_db(): -            self._db_handle = initialize_sqlcipher_db( -                self._opts, check_same_thread=False) -            self._real_replica_uid = None -            self._ensure_schema() -            self.set_document_factory(soledad_doc_factory) - -        return self._defer_to_sync_threadpool(_init_db) - -    def _initialize_sync_threadpool(self): -        """ -        Initialize a ThreadPool with exactly one thread, that will be used to -        run all the network blocking calls for syncing on a separate thread. - -        TODO this needs to be ported away from urllib and into twisted async -        calls, and then we can ditch this syncing thread and reintegrate into -        the main reactor. -        """ -        # XXX if the number of threads in this thread pool is ever changed, we -        #     should make sure that no operations on the database shuold occur -        #     before the database has been initialized. -        self._sync_threadpool = ThreadPool(0, 1) - +    @defer.inlineCallbacks      def sync(self, url, creds=None, defer_decryption=True):          """          Synchronize documents with remote replica exposed at url. -        This method defers a sync to a 1-threaded threadpool. The main -        database initialziation was deferred to that thread during this -        object's initialization. As there's currently only one thread in that -        threadpool, the db init was queued before this method was called, so -        we don't need to actually wait for the db to be ready. If this ever -        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. +        It is not safe to initiate more than one sync process and let them run +        concurrently. It is responsibility of the caller to ensure that there +        are no concurrent sync processes running. This is currently controlled +        by the main Soledad object because it may also run post-sync hooks, +        which should be run while the lock is locked.          :param url: The url of the target replica to sync with.          :type url: str @@ -527,16 +497,10 @@ class SQLCipherU1DBSync(SQLCipherDatabase):          :rtype: Deferred          """          syncer = self._get_syncer(url, creds=creds) - -        def _record_received_docs(result): -            # beware, closure. syncer is in scope. -            self.received_docs = syncer.received_docs -            return result - -        # XXX could mark the critical section here... -        d = syncer.sync(defer_decryption=defer_decryption) -        d.addCallback(_record_received_docs) -        return d +        local_gen_before_sync = yield syncer.sync( +            defer_decryption=defer_decryption) +        self.received_docs = syncer.received_docs +        defer.returnValue(local_gen_before_sync)      def _get_syncer(self, url, creds=None):          """ @@ -589,7 +553,6 @@ class SQLCipherU1DBSync(SQLCipherDatabase):          This should only be called by the shutdown trigger.          """          self.shutdownID = None -        self._sync_threadpool.stop()          self.running = False      def close(self): diff --git a/client/src/leap/soledad/client/sync.py b/client/src/leap/soledad/client/sync.py index deb183ca..110baa0a 100644 --- a/client/src/leap/soledad/client/sync.py +++ b/client/src/leap/soledad/client/sync.py @@ -59,7 +59,8 @@ class SoledadSynchronizer(Synchronizer):                                   decryption will be done inline.          :type defer_decryption: bool -        :return: A deferred which will fire after the sync has finished. +        :return: A deferred which will fire after the sync has finished with +                 the local generation before the synchronization was performed.          :rtype: twisted.internet.defer.Deferred          """          sync_target = self.sync_target  | 
