Exemplo n.º 1
0
    def __heat_fs_path_in_reactor(self, base_dir, base_dir_id, old_path,
                                  new_path):
        """
        Similar to C{__heat_fs_path}, but runs definitely in reactor thread.
        """
        assert in_main_thread()

        with self.__cooling_down_to_store_lock:
            _call_to_store_fs_change = \
                self.__cooling_down_to_store.get(old_path)

            if _call_to_store_fs_change is not None:
                # Some file is being cooled down already.
                # Remove it from the collection,
                # and stop the associated callLater object.
                logger.debug('Reheating the file: %r (%r)', old_path, new_path)
                del self.__cooling_down_to_store[old_path]
                try:
                    _call_to_store_fs_change.cancel()
                except (internet_error.AlreadyCancelled,
                        internet_error.AlreadyCalled):
                    pass
            else:
                # Cooling down a completely new file..
                logger.verbose('Starting to cool down the file: %r', new_path)

            # pylint:disable=E1101,C0103
            _callLater = reactor.callLater
            # pylint:enable=E1101,C0103
            self.__cooling_down_to_store[new_path] = \
                _callLater(FILE_COOL_DOWN_TO_STORE.total_seconds(),
                           lambda: callInThread(
                                       self.__store_fs_change_after_cooling,
                                       base_dir, base_dir_id, new_path))
Exemplo n.º 2
0
    def __try_start_transaction(self):
        """Try to start the PROGRESS transaction.

        It is possible that you don't need to start it actually,
        if the data is empty.

        @note: Deferred callback: exceptions logged.
        """
        assert not in_main_thread()
        logger.debug('Trying to start chunks progress...')

        should_launch_tr = False
        with self.__notification_storage_lock:
            if self.__notification_storage and self.__waiting_for_transaction:
                logger.debug('Starting chunks progress!')
                should_launch_tr = True  # and leave the lock asap!
                # NotificationGetter will deal with the lock properly itself.
                self.__waiting_for_transaction = False

        if should_launch_tr:
            notif_getter = ChunkProgressNotificator.NotificationGetter(self)
            tr = self.app.tr_manager.create_new_transaction(
                     name='PROGRESS',
                     src=self.app.host,
                     dst=self.app.primary_node,
                     parent=None,
                     # PROGRESS-specific
                     host_chunks_map_getter=notif_getter)
Exemplo n.º 3
0
 def _iterate(self, delay=None, fromqt=False):
     _assert(in_main_thread())
     """
     See twisted.internet.interfaces.IReactorCore.iterate.
     """
     self.runUntilCurrent()
     self.doIteration(delay, fromqt)
Exemplo n.º 4
0
    def doIteration(self, delay=None, fromqt=False):
        _assert(in_main_thread())
        """
        This method is called by a Qt timer or by network activity on
        a file descriptor.

        If called becuase of network activiy then control should not
        be handed back to Qt as this would cause recursion.
        """

        if not self.running and self._blockApp:
            self._blockApp.quit()

        self._timer.stop()
        delay = max(delay, 1)
        if not fromqt:
            self.qApp.processEvents(QEventLoop.AllEvents, delay * 1000)
        if self.timeout() is None:
            timeout = 0.1
        elif self.timeout() == 0:
            timeout = 0
        else:
            timeout = self.timeout()
        self._timer.setInterval(timeout * 1000)
        self._timer.start()
Exemplo n.º 5
0
 def removeAll(self):
     _assert(in_main_thread())
     """
     Remove all selectables, and return a list of them.
     """
     rv = self._removeAll(self._reads, self._writes)
     return rv
    def _add_transaction(self, tr, state):
        """Add the transaction to the transaction storage, thread-safely.

        @type tr: AbstractTransaction

        @type state: AbstractTransaction.State
        """
        assert not _TMP_NOTHING_IN_REACTOR_THREAD or not in_main_thread()

        logger.debug("__add %r", tr)

        assert tr.uuid not in self.__transactions_by_uuid, (tr, self.__transactions_by_uuid)

        with self.__transactions_lock:
            self.__transactions_by_uuid[tr.uuid] = tr

            with self.__fdbw_factory() as fdbw:
                FDBQueries.Transactions.add_transaction(
                    type_=tr.type,
                    uuid=tr.uuid,
                    src_uuid=state.tr_src_uuid,
                    dst_uuid=state.tr_dst_uuid,
                    ts=state.tr_start_time,
                    state=state,
                    parent_uuid=None if tr.parent is None else tr.parent.uuid,
                    fdbw=fdbw,
                )
    def _del_transaction(self, tr):
        """
        Delete a transaction from the transaction storage,
        in a thread-safe way.

        @type tr: AbstractTransaction
        """
        assert not _TMP_NOTHING_IN_REACTOR_THREAD or not in_main_thread()

        logger.debug('__del %r', tr)

        assert tr.uuid in self.__transactions_by_uuid, \
               (tr, self.__transactions_by_uuid)

        with self.__transactions_lock:
            del self.__transactions_by_uuid[tr.uuid]

            with self.__fdbw_factory() as fdbw:
                FDBQueries.Transactions.del_transaction(uuid=tr.uuid,
                                                        fdbw=fdbw)

            # Also:
            # All children in progress, unfortunately, should be deleted too
            children_copy = set(tr.children_in_progress)
            map(self._del_transaction, children_copy)
Exemplo n.º 8
0
 def _forward_events(self):
     assert in_main_thread()
     events = self.__forward_later_events
     self.__forward_later_events = set()
     self.__events_to_delay = set()
     for event in events:
         self._forward_event(event)
Exemplo n.º 9
0
    def __try_start_transaction(self):
        """Try to start the PROGRESS transaction.

        It is possible that you don't need to start it actually,
        if the data is empty.

        @note: Deferred callback: exceptions logged.
        """
        assert not in_main_thread()
        logger.debug('Trying to start chunks progress...')

        should_launch_tr = False
        with self.__notification_storage_lock:
            if self.__notification_storage and self.__waiting_for_transaction:
                logger.debug('Starting chunks progress!')
                should_launch_tr = True  # and leave the lock asap!
                # NotificationGetter will deal with the lock properly itself.
                self.__waiting_for_transaction = False

        if should_launch_tr:
            notif_getter = ChunkProgressNotificator.NotificationGetter(self)
            tr = self.app.tr_manager.create_new_transaction(
                name='PROGRESS',
                src=self.app.host,
                dst=self.app.primary_node,
                parent=None,
                # PROGRESS-specific
                host_chunks_map_getter=notif_getter)
    def _add_transaction(self, tr, state):
        """Add the transaction to the transaction storage, thread-safely.

        @type tr: AbstractTransaction

        @type state: AbstractTransaction.State
        """
        assert not _TMP_NOTHING_IN_REACTOR_THREAD or not in_main_thread()

        logger.debug('__add %r', tr)

        assert tr.uuid not in self.__transactions_by_uuid, \
               (tr, self.__transactions_by_uuid)

        with self.__transactions_lock:
            self.__transactions_by_uuid[tr.uuid] = tr

            with self.__fdbw_factory() as fdbw:
                FDBQueries.Transactions.add_transaction(
                    type_=tr.type, uuid=tr.uuid,
                    src_uuid=state.tr_src_uuid, dst_uuid=state.tr_dst_uuid,
                    ts=state.tr_start_time, state=state,
                    parent_uuid=None if tr.parent is None
                                     else tr.parent.uuid,
                    fdbw=fdbw)
Exemplo n.º 11
0
 def shutdown(self):
     _assert(in_main_thread())
     self.notifier.setEnabled(False)
     self.disconnect(self.notifier, SIGNAL("activated(int)"), self.fn)
     self.fn = self.watcher = None
     self.notifier.deleteLater()
     self.deleteLater()
Exemplo n.º 12
0
    def __on_restore_retry_delay_elapsed(self):
        assert not in_main_thread()

        with self.open_state(for_update=True) as state:
            success = self.__request_restoring_more_chunks(state)
        if not success:
            self.__restore_ops_failed()  # outside the state context!
Exemplo n.º 13
0
    def __try_save_next_bunch_of_file_states(self):
        """Check if we have multiple states to store to the DB, and do it."""
        assert not in_main_thread()

        with self.__file_states_ready_to_write_lock:
            all_states = self.__file_states_ready_to_write.values()
            self.__file_states_ready_to_write = {}

        # "states" contains tuples like (base_dir_id, state).
        # Group them by base_dir_id, and write multiple file states at once.

        if all_states:
            logger.debug('Writing %i file state(s) at once',
                         len(all_states))

            grouped_by_base_dir = sorted_groupby(all_states,
                                                 key=itemgetter(0))

            for base_dir_id, per_base_dir in grouped_by_base_dir:
                states_to_write = imap(itemgetter(1), per_base_dir)

                logger.debug('Writing states for base dir %r', base_dir_id)
                with db.RDB() as rdbw:
                    HostQueries.HostFiles.add_file_states(
                        base_dir_id, states_to_write, rdbw)
            logger.debug('Wrote the states')
Exemplo n.º 14
0
 def _forward_events(self):
     assert in_main_thread()
     events = self.__forward_later_events
     self.__forward_later_events = set()
     self.__events_to_delay = set()
     for event in events:
         self._forward_event(event)
Exemplo n.º 15
0
    def mark_as_just_seen_alive(self, key, urls):
        """Implements the @abstractmethod from C{AbstractPeerBook}.

        @type urls: col.Iterable

        @type key: UUID
        """
        assert not in_main_thread()
        with self.__fdbw_factory() as fdbw:
            last_revive_ts = FDBQueries.Users.update_host_info(
                                 host_uuid=HostUUID.safe_cast_uuid(key),
                                 urls=list(urls),
                                 timestamp=datetime.utcnow(),
                                 fdbw=fdbw)

            if last_revive_ts is None:
                # But is this code path supported now?
                logger.debug('Marking %s as alive for the first time', key)
            else:
                was_dead = datetime.utcnow() - last_revive_ts > HOST_DEATH_TIME
                if was_dead:
                    logger.debug('Marking %s as just seen alive, was dead',
                                 key)
                else:
                    logger.verbose('Marking %s as just seen alive, was alive',
                                   key)
Exemplo n.º 16
0
        def add_message(cls, msg, bdbw):
            """Add a new outgoing message.

            @param msg: an outgoing message to put in the message pool.
            @type msg: AbstractMessage

            @param bdbw: BigDB wrapper.
            @type bdbw: abstract_docstorewrapper.AbstractDocStoreWrapper
            """
            assert not in_main_thread()  # get_body() may take long

            # Mandatory
            args = {
                'name': msg.name,
                'ack': msg.is_ack,
                'active': True,
                'uuid': msg.uuid,
                'src': msg.src.uuid,
                'dst': msg.dst.uuid,
            }

            # Optional
            if msg.status_code != 0:
                args['status_code'] = msg.status_code

            bdbw.retried_sync(bdbw.gfs_messages.put,
                              ''.join(msg.get_body()),
                              **args)
Exemplo n.º 17
0
    def mark_as_just_seen_alive(self, key, urls):
        """Implements the @abstractmethod from C{AbstractPeerBook}.

        @type urls: col.Iterable

        @type key: UUID
        """
        assert not in_main_thread()
        with self.__fdbw_factory() as fdbw:
            last_revive_ts = FDBQueries.Users.update_host_info(
                host_uuid=HostUUID.safe_cast_uuid(key),
                urls=list(urls),
                timestamp=datetime.utcnow(),
                fdbw=fdbw)

            if last_revive_ts is None:
                # But is this code path supported now?
                logger.debug('Marking %s as alive for the first time', key)
            else:
                was_dead = datetime.utcnow() - last_revive_ts > HOST_DEATH_TIME
                if was_dead:
                    logger.debug('Marking %s as just seen alive, was dead',
                                 key)
                else:
                    logger.verbose('Marking %s as just seen alive, was alive',
                                   key)
Exemplo n.º 18
0
    def _received_http_response(self, response_tuple, orig_message):
        """Overrides method from C{HostApp}."""
        assert in_main_thread()
        self.network_connection_is_working = True

        return super(UHostApp, self)._received_http_response(response_tuple,
                                                             orig_message)
Exemplo n.º 19
0
    def _received_http_response(self, response_tuple, orig_message):
        """Overrides method from C{HostApp}."""
        assert in_main_thread()
        self.network_connection_is_working = True

        return super(UHostApp,
                     self)._received_http_response(response_tuple,
                                                   orig_message)
Exemplo n.º 20
0
    def unwatch_paths(self, paths):
        """Stop watching several paths.

        @type paths: col.Iterable
        """
        assert in_main_thread()
        for path in paths:
            self.unwatch_path(path)
Exemplo n.º 21
0
 def __on_event(self, event):
     assert in_main_thread()
     if event in self.__events_to_delay:
         self.__forward_later_events.add(event)
     else:
         self.__forward_now_events.add(event)
         self.__events_to_delay.add(event)
     self.do_forward_events()
Exemplo n.º 22
0
 def __on_next_iteration_of_file_state_bunch(self):
     assert in_main_thread()
     d = threads.deferToThread(
             lambda: exceptions_logged(logger)(
                         self.__try_save_next_bunch_of_file_states)())
     d.addBoth(lambda ignore:
                   exceptions_logged(logger)(
                       self.__do_next_iteration_of_file_state_bunch)())
Exemplo n.º 23
0
    def unwatch_paths(self, paths):
        """Stop watching several paths.

        @type paths: col.Iterable
        """
        assert in_main_thread()
        for path in paths:
            self.unwatch_path(path)
Exemplo n.º 24
0
 def do_forward_events(self):
     assert in_main_thread()
     events = self.__forward_now_events
     self.__forward_now_events = set()
     for event in events:
         self._forward_event(event)
     if not self._delayed_forward.active():
         self.__relaunch_delayed_forward()
Exemplo n.º 25
0
 def do_forward_events(self):
     assert in_main_thread()
     events = self.__forward_now_events
     self.__forward_now_events = set()
     for event in events:
         self._forward_event(event)
     if not self._delayed_forward.active():
         self.__relaunch_delayed_forward()
    def get_tr_by_uuid(self, tr_uuid):
        """Implementation of interface from C{AbstractTransactionManager}.

        @rtype: AbstractTransaction, NoneType
        """
        assert not _TMP_NOTHING_IN_REACTOR_THREAD or not in_main_thread()

        return self.__transactions_by_uuid.get(tr_uuid)
Exemplo n.º 27
0
 def run(self, installSignalHandlers=True):
     _assert(in_main_thread())
     if self._ownApp:
         self._blockApp = self.qApp
     else:
         self._blockApp = QEventLoop()
     self.runReturn()
     self._blockApp.exec_()
Exemplo n.º 28
0
 def __on_event(self, event):
     assert in_main_thread()
     if event in self.__events_to_delay:
         self.__forward_later_events.add(event)
     else:
         self.__forward_now_events.add(event)
         self.__events_to_delay.add(event)
     self.do_forward_events()
    def get_tr_by_uuid(self, tr_uuid):
        """Implementation of interface from C{AbstractTransactionManager}.

        @rtype: AbstractTransaction, NoneType
        """
        assert not _TMP_NOTHING_IN_REACTOR_THREAD or not in_main_thread()

        return self.__transactions_by_uuid.get(tr_uuid)
Exemplo n.º 30
0
    def __do_next_iteration_of_file_state_bunch(self):
        """Go the next iteration of file state bunch write to the DB."""
        assert in_main_thread()

        # pylint:disable=E1101,C0103
        _callLater = reactor.callLater
        # pylint:enable=E1101,C0103
        _callLater(FILE_BUNCH_COOL_DOWN_TO_STORE.total_seconds(),
                   self.__on_next_iteration_of_file_state_bunch)
Exemplo n.º 31
0
    def wait_for_message_for_peer(self,
                                  inh,
                                  prefer_msg_uuid,
                                  still_wait_checker,
                                  d=None):
        """Implementation of interface from C{AbstractTransactionManager}.

        @type inh: AbstractInhabitant
        @type prefer_msg_uuid: MessageUUID, NoneType
        @type still_wait_checker: col.Callable
        @type d: defer.Deferred, NoneType
        @rtype: defer.Deferred

        @todo: C{still_wait_checker} is not used; instead, the user should
            probably delete the C{Deferred} from
            C{__outgoing_message_notifs_by_host_uuid}.
        """
        assert not in_main_thread()

        d = defer.Deferred() if d is None else d

        with self.__outgoing_messages_lock:
            # Do we have a message with the preferred UUID?
            candidate_msg = \
                self.__outgoing_messages_by_uuid.get(prefer_msg_uuid, None)

            # Do we have a message for a particular peer?
            reply_msg = self.deliver_message_for_peer(inh, prefer_msg_uuid)

            # What if we would try to deliver a message with a particular
            # UUID? Too lazy to implement it now (cause it's not needed at the
            # moment), but... could it help us?
            #
            if reply_msg is not None:
                # For now, if we have a reply message for some particular peer,
                # this takes precedence over the reply message
                # we could send to.
                # This might be wrong though.
                # Note that coalesce() may return a msg,
                # and reply_msg may be None, so we'd better compare them
                # only if reply_msg is definitely not None.
                if coalesce(candidate_msg, reply_msg) != reply_msg:
                    logger.warning("Could've deliver %r, but using %r instead",
                                   candidate_msg, reply_msg)

                # We have an outgoing message for inh already!
                d.callback(reply_msg)
            else:
                # Unfortunately, we don't have a message yet.
                # We have to put a deferred callback to the queue
                # for this peer.
                # Whenever a message directed to this host is added,
                # the message adder will call this callback.
                self.__outgoing_message_notifs_by_host_uuid[inh.uuid] \
                    .append(d)

        return d
Exemplo n.º 32
0
    def __do_next_iteration_of_file_state_bunch(self):
        """Go the next iteration of file state bunch write to the DB."""
        assert in_main_thread()

        # pylint:disable=E1101,C0103
        _callLater = reactor.callLater
        # pylint:enable=E1101,C0103
        _callLater(FILE_BUNCH_COOL_DOWN_TO_STORE.total_seconds(),
                   self.__on_next_iteration_of_file_state_bunch)
    def wait_for_message_for_peer(self,
                                  inh, prefer_msg_uuid, still_wait_checker,
                                  d=None):
        """Implementation of interface from C{AbstractTransactionManager}.

        @type inh: AbstractInhabitant
        @type prefer_msg_uuid: MessageUUID, NoneType
        @type still_wait_checker: col.Callable
        @type d: defer.Deferred, NoneType

        @returns: a deferred that fires with the message, or maybe
            a {error.ConnectionClosed()}.
        @rtype: defer.Deferred
        """
        assert not in_main_thread()

        if d is None:
            logger.debug('Checking for message for %r', inh)
        else:
            logger.debug('1 second passed, polling a message for %r', inh)

        d = defer.Deferred() if d is None else d

        if not still_wait_checker():
            logger.debug("Seems like we don't need to wait for %r anymore",
                         inh)
            d.errback(error.ConnectionClosed(u'No need to wait on {!r}'
                                                 .format(inh)))

        else:
            logger.debug("Let's deliver a message for %r, preferrably %r",
                         inh, prefer_msg_uuid)
            reply_msg = self.deliver_message_for_peer(inh, prefer_msg_uuid)
            assert isinstance(reply_msg, (AbstractMessage, NoneType)), \
                   repr(reply_msg)

            if reply_msg is not None:
                # We have an outgoing message for inh already!
                logger.verbose('Going to deliver a message for %r: %r',
                               inh, reply_msg)
                d.callback(reply_msg)
            else:
                # Unfortunately, we don't have a message yet.
                # Let's recall this function in, say, a second.
                logger.verbose('No messages for %r, retrying in %r',
                               inh, POLL_FOR_OUTGOING_MESSAGES_PERIOD)

                callFromThread(
                    task.deferLater,
                    reactor,
                    POLL_FOR_OUTGOING_MESSAGES_PERIOD.total_seconds(),
                    lambda: callInThread(
                                self.__wait_for_message_for_peer_ignore_result,
                                inh, prefer_msg_uuid, still_wait_checker, d))

        return d
Exemplo n.º 34
0
    def _add(self, xer, primary, type):
        _assert(in_main_thread())
        """
        Private method for adding a descriptor from the event loop.

        It takes care of adding it if  new or modifying it if already added
        for another state (read -> read/write for example).
        """
        if xer not in primary:
            primary[xer] = TwistedSocketNotifier(None, self, xer, type)
Exemplo n.º 35
0
    def wait_for_message_for_peer(self,
                                  inh, prefer_msg_uuid, still_wait_checker,
                                  d=None):
        """Implementation of interface from C{AbstractTransactionManager}.

        @type inh: AbstractInhabitant
        @type prefer_msg_uuid: MessageUUID, NoneType
        @type still_wait_checker: col.Callable
        @type d: defer.Deferred, NoneType
        @rtype: defer.Deferred

        @todo: C{still_wait_checker} is not used; instead, the user should
            probably delete the C{Deferred} from
            C{__outgoing_message_notifs_by_host_uuid}.
        """
        assert not in_main_thread()

        d = defer.Deferred() if d is None else d

        with self.__outgoing_messages_lock:
            # Do we have a message with the preferred UUID?
            candidate_msg = \
                self.__outgoing_messages_by_uuid.get(prefer_msg_uuid, None)

            # Do we have a message for a particular peer?
            reply_msg = self.deliver_message_for_peer(inh, prefer_msg_uuid)

            # What if we would try to deliver a message with a particular
            # UUID? Too lazy to implement it now (cause it's not needed at the
            # moment), but... could it help us?
            #
            if reply_msg is not None:
                # For now, if we have a reply message for some particular peer,
                # this takes precedence over the reply message
                # we could send to.
                # This might be wrong though.
                # Note that coalesce() may return a msg,
                # and reply_msg may be None, so we'd better compare them
                # only if reply_msg is definitely not None.
                if coalesce(candidate_msg, reply_msg) != reply_msg:
                    logger.warning("Could've deliver %r, but using %r instead",
                                   candidate_msg, reply_msg)

                # We have an outgoing message for inh already!
                d.callback(reply_msg)
            else:
                # Unfortunately, we don't have a message yet.
                # We have to put a deferred callback to the queue
                # for this peer.
                # Whenever a message directed to this host is added,
                # the message adder will call this callback.
                self.__outgoing_message_notifs_by_host_uuid[inh.uuid] \
                    .append(d)

        return d
Exemplo n.º 36
0
    def add(self, dst_peer, chunks, end_ts, duration):
        """
        Add a notification that some chunks were successfully uploaded
        to the dst_peer on end_ts, taking duration.

        @type chunks: (list, set)
        @precondition: consists_of(chunks, Chunk)

        @param dst_peer: The Host,
                         to which the chunks were uploaded before.
        @type dst_peer: Host

        @param end_ts: When the upload of these chunks was completed?
        @type end_ts: datetime

        @param duration: How much time did the upload of the chunks took?
        @type duration: timedelta

        @rtype: Deferred
        """
        assert not in_main_thread()
        result_deferred = Deferred()
        _notification = \
            ProgressNotificationPerHostWithDeferred(chunks=chunks,
                                                    end_ts=end_ts,
                                                    duration=duration,
                                                    deferred=result_deferred)

        logger.debug('Adding progress... ')

        should_launch_calllater = False

        with self.__notification_storage_lock:
            # First, create and add the information about the group of chunks.
            self.__notification_storage.setdefault(dst_peer, []) \
                                     .append(_notification)

            # Then, if the transaction is not yet pending,
            # let's plan to run the transaction in several seconds.
            if not self.__waiting_for_transaction:
                should_launch_calllater = self.__waiting_for_transaction = True
                # ... and leave the lock ASAP!

                # Since this moment, self.__notification_storage_lock
                # is redundant.

        # Outside of the lock!!!
        if should_launch_calllater:
            callLaterInThread(WAIT_TO_COLLECT_PROGRESS_BEFORE_SEND,
                              self.__try_start_transaction)

        logger.debug('Will wait for %i chunks to %r with %r', len(chunks),
                     dst_peer, result_deferred)

        return result_deferred
Exemplo n.º 37
0
    def add(self, dst_peer, chunks, end_ts, duration):
        """
        Add a notification that some chunks were successfully uploaded
        to the dst_peer on end_ts, taking duration.

        @type chunks: (list, set)
        @precondition: consists_of(chunks, Chunk)

        @param dst_peer: The Host,
                         to which the chunks were uploaded before.
        @type dst_peer: Host

        @param end_ts: When the upload of these chunks was completed?
        @type end_ts: datetime

        @param duration: How much time did the upload of the chunks took?
        @type duration: timedelta

        @rtype: Deferred
        """
        assert not in_main_thread()
        result_deferred = Deferred()
        _notification = \
            ProgressNotificationPerHostWithDeferred(chunks=chunks,
                                                    end_ts=end_ts,
                                                    duration=duration,
                                                    deferred=result_deferred)

        logger.debug('Adding progress... ')

        should_launch_calllater = False

        with self.__notification_storage_lock:
            # First, create and add the information about the group of chunks.
            self.__notification_storage.setdefault(dst_peer, []) \
                                     .append(_notification)

            # Then, if the transaction is not yet pending,
            # let's plan to run the transaction in several seconds.
            if not self.__waiting_for_transaction:
                should_launch_calllater = self.__waiting_for_transaction = True
                # ... and leave the lock ASAP!

                # Since this moment, self.__notification_storage_lock
                # is redundant.

        # Outside of the lock!!!
        if should_launch_calllater:
            callLaterInThread(WAIT_TO_COLLECT_PROGRESS_BEFORE_SEND,
                              self.__try_start_transaction)

        logger.debug('Will wait for %i chunks to %r with %r',
                     len(chunks), dst_peer, result_deferred)

        return result_deferred
Exemplo n.º 38
0
    def _when_starting_normal_mode(self):
        """Overrides method from C{HostApp}."""
        assert in_main_thread()

        super(UHostApp, self)._when_starting_normal_mode()

        _callLater = reactor.callLater  # pylint:disable=E1101,C0103

        self.__syncer_starter = \
            _callLater(START_SYNCING_AFTER.total_seconds(),
                       lambda: callInThread(self.__start_syncing))
Exemplo n.º 39
0
    def _handle_changes_in_file(self, path):
        assert not in_main_thread()
        try:
            mode = os.stat(path).st_mode
        except OSError:
            # file deletion will handled on directory changed signal
            return
        else:
            assert stat.S_ISREG(mode), (path, mode)

        self._send_event(ModifyEvent, path)
Exemplo n.º 40
0
    def _when_starting_normal_mode(self):
        """Overrides method from C{HostApp}."""
        assert in_main_thread()

        super(UHostApp, self)._when_starting_normal_mode()

        _callLater = reactor.callLater  # pylint:disable=E1101,C0103

        self.__syncer_starter = \
            _callLater(START_SYNCING_AFTER.total_seconds(),
                       lambda: callInThread(self.__start_syncing))
Exemplo n.º 41
0
    def _remove(self, xer, primary):
        _assert(in_main_thread())
        """
        Private method for removing a descriptor from the event loop.

        It does the inverse job of _add, and also add a check in case of the fd
        has gone away.
        """
        if xer in primary:
            notifier = primary.pop(xer)
            notifier.shutdown()
Exemplo n.º 42
0
    def _handle_changes_in_file(self, path):
        assert not in_main_thread()
        try:
            mode = os.stat(path).st_mode
        except OSError:
            # file deletion will handled on directory changed signal
            return
        else:
            assert stat.S_ISREG(mode), (path, mode)

        self._send_event(ModifyEvent, path)
    def post_message(self, message):
        """Implementation of interface from C{AbstractTransactionManager}.

        @type message: AbstractMessage
        """
        assert not _TMP_NOTHING_IN_REACTOR_THREAD or not in_main_thread()

        super(TransactionManagerInFastDBBigDB, self).post_message(message)

        logger.verbose("Posting message %r", message)
        with self.__bdbw_factory() as bdbw:
            BDBQueries.Messages.add_message(msg=message, bdbw=bdbw)
Exemplo n.º 44
0
    def __on_create_dataset_timer(self):
        assert not in_main_thread()

        if (self.is_started and self.do_send_messages
                and self.do_heartbeats_revive):
            # We are running the "main living loop"
            logger.debug('Trying to create dataset...')
            try:
                self.__backup_snapshotted_files_if_needed()
            except Exception:
                logger.exception('A error occured during '
                                 'regular backup attempt.')
    def post_message(self, message):
        """Implementation of interface from C{AbstractTransactionManager}.

        @type message: AbstractMessage
        """
        assert not _TMP_NOTHING_IN_REACTOR_THREAD or not in_main_thread()

        super(TransactionManagerInFastDBBigDB, self).post_message(message)

        logger.verbose('Posting message %r', message)
        with self.__bdbw_factory() as bdbw:
            BDBQueries.Messages.add_message(msg=message, bdbw=bdbw)
Exemplo n.º 46
0
    def _error_on_send_http_request(self, failure, message):
        """Overrides method from C{HostApp}."""
        assert in_main_thread()

        if failure.check(internet_error.ConnectionRefusedError,
                         internet_error.ConnectionDone,
                         internet_error.ConnectionLost,
                         internet_error.DNSLookupError):
            self.network_connection_is_working = False

        return super(UHostApp,
                     self)._error_on_send_http_request(failure, message)
Exemplo n.º 47
0
    def _error_on_send_http_request(self, failure, message):
        """Overrides method from C{HostApp}."""
        assert in_main_thread()

        if failure.check(internet_error.ConnectionRefusedError,
                         internet_error.ConnectionDone,
                         internet_error.ConnectionLost,
                         internet_error.DNSLookupError):
            self.network_connection_is_working = False

        return super(UHostApp, self)._error_on_send_http_request(failure,
                                                                 message)
Exemplo n.º 48
0
    def __on_create_dataset_timer(self):
        assert not in_main_thread()

        if (self.is_started and
            self.do_send_messages and
            self.do_heartbeats_revive):
           # We are running the "main living loop"
            logger.debug('Trying to create dataset...')
            try:
                self.__backup_snapshotted_files_if_needed()
            except Exception:
                logger.exception('A error occured during '
                                     'regular backup attempt.')
    def deliver_message_for_peer(self, inh, prefer_msg_uuid):
        """Implementation of interface from C{AbstractTransactionManager}.

        @type inh: AbstractInhabitant
        @type prefer_msg_uuid: MessageUUID, NoneType
        @rtype: AbstractMessage, NoneType
        """
        assert not _TMP_NOTHING_IN_REACTOR_THREAD or not in_main_thread()

        with self.__bdbw_factory() as bdbw:
            return BDBQueries.Messages.take_message_for_peer(
                my_node=self.app.server_process.me, dst_uuid=inh.uuid, prefer_msg_uuid=prefer_msg_uuid, bdbw=bdbw
            )
Exemplo n.º 50
0
 def __init__(self, parent, reactor, watcher, socketType):
     _assert(in_main_thread())
     QObject.__init__(self, parent)
     self.reactor = reactor
     self.watcher = watcher
     fd = watcher.fileno()
     self.notifier = QSocketNotifier(fd, socketType, parent)
     self.notifier.setEnabled(True)
     if socketType == QSocketNotifier.Read:
         self.fn = self.read
     else:
         self.fn = self.write
     QObject.connect(self.notifier, SIGNAL("activated(int)"), self.fn)
Exemplo n.º 51
0
    def __cbDigestMatch(self, matched, username, host_uuids, msgtype):
        """
        @returns: Either the tuple of user of the peer being authenticated
            and its possible host candidates; or a C{Failure} object.
        @rtype: AuthAvatar, Failure
        """
        assert in_main_thread()

        logger.debug("Digest for %r: %s", username, "matched" if matched else "mismatched")
        if matched:
            return AuthAvatar(username=username, host_uuid_candidates=host_uuids, do_create=(msgtype == "LOGIN"))
        else:
            return Failure(cred_error.UnauthorizedLogin())