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
Example #2
0
    def __start_syncing(self):
        """
        Scan the watched directory for the changes happened offline,
        and launch the online dir watcher
        """
        assert not in_main_thread()
        cls = self.__class__
        logger.debug('Starting syncing...')

        if __debug__ and _TMP_ENABLE_DUMMY_DATA_TRANSFER_VENTILATOR:
            from .mocks import _start_dummy_data_transfer_ventilator
            _start_dummy_data_transfer_ventilator()

        watched_directories = host_settings.get_selected_paths()

        if watched_directories is None:
            logger.debug('No paths to backup setting, not syncing')
        else:
            _watched_dirs_len = len(watched_directories)
            if _watched_dirs_len != 1:
                logger.error('%i directories to be synced instead of 1, '
                                 'not syncing anything then: %s',
                             _watched_dirs_len, watched_directories)
            else:
                _ugroup_uuid = self.host.user.base_group.uuid

                watched_dir = watched_directories.iterkeys().next()
                with db.RDB() as rdbw:
                    base_dir_id = \
                        HostQueries.HostFiles.add_or_get_base_directory(
                            watched_dir, _ugroup_uuid, rdbw)

                logger.debug('Checking the directory %s for offline changes',
                             watched_dir)
                cls.take_base_directory_snapshot(watched_dir, _ugroup_uuid)
                logger.debug('Snapshot taken!')

                # We are here after all preparations has been done (and maybe,
                # even the backup was started for the files which were changed
                # offline before the host restart).
                #
                # At this point, we are going to start the directory tracker.
                logger.debug('Enabling the FS notification watcher for %r',
                             watched_dir)

                callFromThread(self.__fsnotify_manager.watch,
                                watched_dir,
                                partial(self.__on_fs_change,
                                        watched_dir, base_dir_id))
                callFromThread(self.__do_next_iteration_of_file_state_bunch)
Example #3
0
    def __start_syncing(self):
        """
        Scan the watched directory for the changes happened offline,
        and launch the online dir watcher
        """
        assert not in_main_thread()
        cls = self.__class__
        logger.debug('Starting syncing...')

        if __debug__ and _TMP_ENABLE_DUMMY_DATA_TRANSFER_VENTILATOR:
            from .mocks import _start_dummy_data_transfer_ventilator
            _start_dummy_data_transfer_ventilator()

        watched_directories = host_settings.get_selected_paths()

        if watched_directories is None:
            logger.debug('No paths to backup setting, not syncing')
        else:
            _watched_dirs_len = len(watched_directories)
            if _watched_dirs_len != 1:
                logger.error(
                    '%i directories to be synced instead of 1, '
                    'not syncing anything then: %s', _watched_dirs_len,
                    watched_directories)
            else:
                _ugroup_uuid = self.host.user.base_group.uuid

                watched_dir = watched_directories.iterkeys().next()
                with db.RDB() as rdbw:
                    base_dir_id = \
                        HostQueries.HostFiles.add_or_get_base_directory(
                            watched_dir, _ugroup_uuid, rdbw)

                logger.debug('Checking the directory %s for offline changes',
                             watched_dir)
                cls.take_base_directory_snapshot(watched_dir, _ugroup_uuid)
                logger.debug('Snapshot taken!')

                # We are here after all preparations has been done (and maybe,
                # even the backup was started for the files which were changed
                # offline before the host restart).
                #
                # At this point, we are going to start the directory tracker.
                logger.debug('Enabling the FS notification watcher for %r',
                             watched_dir)

                callFromThread(
                    self.__fsnotify_manager.watch, watched_dir,
                    partial(self.__on_fs_change, watched_dir, base_dir_id))
                callFromThread(self.__do_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
Example #5
0
    def __heat_fs_path(self, base_dir, base_dir_id, old_path, new_path):
        """
        "Reheat" (or just start heating) the file path
        in the cooling-down mechanism.

        @param old_path: the previous name of the path.
            May be equal to C{new_path}, but not necessarily.
        @type old_path: basestring

        @param new_path: the new name of the path.
            May be equal to C{old_path}, but not necessarily.
        @type new_path: basestring

        @note: may be called either in reactor thread or in threadpool thread,
            no guarantees.
        """
        callFromThread(self.__heat_fs_path_in_reactor,
                       base_dir, base_dir_id, old_path, new_path)
Example #6
0
    def __heat_fs_path(self, base_dir, base_dir_id, old_path, new_path):
        """
        "Reheat" (or just start heating) the file path
        in the cooling-down mechanism.

        @param old_path: the previous name of the path.
            May be equal to C{new_path}, but not necessarily.
        @type old_path: basestring

        @param new_path: the new name of the path.
            May be equal to C{old_path}, but not necessarily.
        @type new_path: basestring

        @note: may be called either in reactor thread or in threadpool thread,
            no guarantees.
        """
        callFromThread(self.__heat_fs_path_in_reactor, base_dir, base_dir_id,
                       old_path, new_path)
Example #7
0
 def _remove_paths_from_watcher(self, paths):
     """
     @type paths: col.Iterable
     """
     callFromThread(self._fs_watcher.unwatch_paths, paths)
Example #8
0
 def _add_paths_to_watcher(self, paths):
     callFromThread(self._fs_watcher.watch_paths, paths)
Example #9
0
 def _remove_paths_from_watcher(self, paths):
     """
     @type paths: col.Iterable
     """
     callFromThread(self._fs_watcher.unwatch_paths, paths)
Example #10
0
 def _add_paths_to_watcher(self, paths):
     callFromThread(self._fs_watcher.watch_paths, paths)