Esempio n. 1
0
    def on_error(self, task=None):
        '''
        Called when an error occurs. task is a callable that can be used to make another attempt
        at whatever caused the error (if error_count is less than max_error).
        '''
        self.error_count += 1

        log.error('%r\'s error count is now: %d',self, self.error_count)
        log.error('on_error called from %s', get_func_name(2))

        if self.error_count < pref('email.err_max_tolerance', self.error_max):
            if task is None:
                task = self.update_now
            log.error('error count is under, calling %r now', task)

            if not callable(task):
                # If it was an exception assume that update_now was called. (the account type
                # probably just hasn't been fixed yet
                task = self.update_now
            util.call_later(pref('email.err_retry_time', type=int, default=2), task)
        else:
            log.error('assuming the connection has died')
            self.set_offline(self.Reasons.CONN_FAIL)
            self.error_count = 0

        del self.emails[:]
Esempio n. 2
0
    def on_error(self, task=None):
        '''
        Called when an error occurs. task is a callable that can be used to make another attempt
        at whatever caused the error (if error_count is less than max_error).
        '''
        self.error_count += 1

        log.error('%r\'s error count is now: %d', self, self.error_count)
        log.error('on_error called from %s', get_func_name(2))

        if self.error_count < pref('email.err_max_tolerance', self.error_max):
            if task is None:
                task = self.update_now
            log.error('error count is under, calling %r now', task)

            if not callable(task):
                # If it was an exception assume that update_now was called. (the account type
                # probably just hasn't been fixed yet
                task = self.update_now
            util.call_later(pref('email.err_retry_time', type=int, default=2),
                            task)
        else:
            log.error('assuming the connection has died')
            self.set_offline(self.Reasons.CONN_FAIL)
            self.error_count = 0

        del self.emails[:]
Esempio n. 3
0
    def Send(self, msg, callback = None, **kw):
        self.ResetTimeoutTimer()

        if msg is None:
            import traceback; traceback.print_stack()

        self.sessionMessages.append((msg, callback, kw))
        util.call_later(0, self.event, 'Messages', self)
Esempio n. 4
0
 def _NH_FileTransferHandlerDidEnd(self, notification):
     if self.direction == 'incoming':
         if self.stream.direction == 'sendonly':
             call_later(3, self.session.end)
         else:
             call_later(1, self.session.end)
     else:
         self.session.end()
     self._terminate(failure_reason=notification.data.reason)
Esempio n. 5
0
 def dc_SendCompleted(self, session, msg):
     util.call_later(0, self.OnBridgeSent, session, msg)
Esempio n. 6
0
 def Connect(self):
     self.change_reason(self.Reasons.NONE)
     call_later(1.5, self.update)
Esempio n. 7
0
    def on_offline_change(self, src, attr, old, new):
        accounts_debug('%s\'s %s changed from %s to %s', src, attr, old, new)
        assert attr in ('offline_reason', None)
        attr = 'offline_reason'
        if new is None:
            new = getattr(src, attr)
        Reasons = StateMixin.Reasons

        conditions = (
            old ==
            new,  # no change...this function shouldn't have been called in the first place
            new ==
            StateMixin.Reasons.NONE,  # normal offline state, doesn't matter
        )

        if any(conditions):
            return

        log.debug('%s offline reason: %r->%r', src, old, new)

        if getattr(Reasons, 'WILL_RECONNECT', None) in (new, old):
            # something we set - ignore for now
            # new means we set it lower down in this function, old means we're moving out of this state, which should
            # not be an error.
            log.debug('Skipping the rest because reason is WILL_RECONNECT')
            return

        if new == getattr(Reasons, 'BAD_PASSWORD',
                          None) and src is self.profile:
            if not self.profile.has_authorized:
                log.debug(
                    'Wrong password for digsbyprofile - not going to reconnect'
                )
                return
            else:
                new = None

        if src is self.profile and not self.profile.loaded:
            log.debug(
                'DigsbyProfile has never connected, not reconnecting after %s state.',
                new)
            return

        if (is_im_account(src) or src is self.profile) and new not in (
                Reasons.BAD_PASSWORD, Reasons.NO_MAILBOX, Reasons.OTHER_USER,
                Reasons.RATE_LIMIT, Reasons.SERVER_ERROR):

            maxerror = (pref('%s.max_error_tolerance' % src.protocol, False)
                        or getattr(src, 'max_error_tolerance', False)
                        or pref('login.max_error_tolerance', False) or 4)

            count = src.error_count
            src.error_count += 1
            log.info(
                '%s\'s error_count is now %d.',
                src,
                src.error_count,
            )

            if (self.reconnect or src is self.profile):  #and count < maxerror:
                if src in self.reconnect_timers:
                    src.error_count -= 1
                    # account is already scheduled for a reconnect
                    return

                src.setnotifyif('offline_reason', Reasons.WILL_RECONNECT)
                # schedule/attempt reconnect
                reconnect_time = get((1, 10, 30, 300), count, 300)

                if src in self.accounts or src is self.profile:
                    profile_on_return = False
                    if src is self.profile:
                        log.critical(
                            'Going to try to reconnect the digsbyprofile. This could get interesting...'
                        )
                        reconnect_time, profile_on_return = self.get_profile_reconnect_time(
                        )

                    def rct():
                        log.info('Reconnecting %s...', src)
                        try:
                            log.warning(
                                'src=%r...setting on_connect to change_state',
                                src)
                            if src is self.profile:

                                def set_online(*a, **k):
                                    src.connection.setnotify(
                                        'state', StateMixin.Statuses.ONLINE)

                                src.on_connect = set_online
                            if getattr(src, 'connection', None) is None:
                                src._reconnect()
                            else:
                                log.error(
                                    'There was already a connection for this account that was supposed to reconnect: %r',
                                    src)
                        except Exception, e:
                            log.critical(
                                'Error while trying to reconnect %s (error was: %r)',
                                src, e)
                            traceback.print_exc()
                        x = self.reconnect_timers.pop(src, None)
                        if x is not None:
                            x.stop()

                    log.info(
                        'Starting reconnect timer for %s. Will reconnect in %d seconds %r',
                        src, reconnect_time, self.state_desc(src))
                    self.reconnect_timers[src] = rct_timer = call_later(
                        reconnect_time, threaded(rct))

                    if profile_on_return:

                        def reconnect_profile_now(*a, **k):
                            rct_timer.done_at = 0
                            wakeup_timeout_thread()

                        self.profile.OnReturnFromIdle += reconnect_profile_now

                    return
                else:
                    assert isinstance(src, UpdateMixin)
                    # this is a social or email account -- it has its own timers and things
                    # and will attempt the next update when appropriate
                    return

            log.info('Error count too high, or reconnect disabled.')
Esempio n. 8
0
    def on_offline_change(self, src, attr, old, new):
        accounts_debug('%s\'s %s changed from %s to %s', src, attr, old, new)
        assert attr in ('offline_reason', None)
        attr = 'offline_reason'
        if new is None:
            new = getattr(src, attr)
        Reasons = StateMixin.Reasons

        conditions = (old       == new,                          # no change...this function shouldn't have been called in the first place
                      new       == StateMixin.Reasons.NONE,      # normal offline state, doesn't matter
                      )

        if any(conditions):
            return

        log.debug('%s offline reason: %r->%r', src, old, new)


        if getattr(Reasons, 'WILL_RECONNECT', None) in (new, old):
            # something we set - ignore for now
            # new means we set it lower down in this function, old means we're moving out of this state, which should
            # not be an error.
            log.debug('Skipping the rest because reason is WILL_RECONNECT')
            return

        if new == getattr(Reasons, 'BAD_PASSWORD', None) and src is self.profile:
            if not self.profile.has_authorized:
                log.debug('Wrong password for digsbyprofile - not going to reconnect')
                return
            else:
                new = None

        if src is self.profile and not self.profile.loaded:
            log.debug('DigsbyProfile has never connected, not reconnecting after %s state.', new)
            return


        if (is_im_account(src) or src is self.profile) and new not in (Reasons.BAD_PASSWORD, Reasons.NO_MAILBOX,
                       Reasons.OTHER_USER, Reasons.RATE_LIMIT, Reasons.SERVER_ERROR):

            maxerror = (pref('%s.max_error_tolerance' % src.protocol, False) or
                        getattr(src, 'max_error_tolerance', False) or
                        pref('login.max_error_tolerance', False) or

                        4

                        )

            count = src.error_count
            src.error_count += 1
            log.info('%s\'s error_count is now %d.', src, src.error_count,)


            if (self.reconnect or src is self.profile): #and count < maxerror:
                if src in self.reconnect_timers:
                    src.error_count -= 1
                    # account is already scheduled for a reconnect
                    return

                src.setnotifyif('offline_reason', Reasons.WILL_RECONNECT)
                # schedule/attempt reconnect
                reconnect_time = get((1,10,30,300), count, 300)

                if src in self.accounts or src is self.profile:
                    profile_on_return = False
                    if src is self.profile:
                        log.critical('Going to try to reconnect the digsbyprofile. This could get interesting...')
                        reconnect_time, profile_on_return = self.get_profile_reconnect_time()

                    def rct():
                        log.info('Reconnecting %s...', src)
                        try:
                            log.warning('src=%r...setting on_connect to change_state', src)
                            if src is self.profile:
                                def set_online(*a, **k):
                                    src.connection.setnotify('state', StateMixin.Statuses.ONLINE)
                                src.on_connect = set_online
                            if getattr(src, 'connection', None) is None:
                                src._reconnect()
                            else:
                                log.error('There was already a connection for this account that was supposed to reconnect: %r', src)
                        except Exception, e:
                            log.critical('Error while trying to reconnect %s (error was: %r)', src, e)
                            traceback.print_exc()
                        x = self.reconnect_timers.pop(src,None)
                        if x is not None:
                            x.stop()

                    log.info('Starting reconnect timer for %s. Will reconnect in %d seconds %r', src, reconnect_time, self.state_desc(src))
                    self.reconnect_timers[src] = rct_timer = call_later(reconnect_time, threaded(rct))

                    if profile_on_return:
                        def reconnect_profile_now(*a, **k):
                            rct_timer.done_at = 0
                            wakeup_timeout_thread()
                        self.profile.OnReturnFromIdle += reconnect_profile_now

                    return
                else:
                    assert isinstance(src, UpdateMixin)
                    # this is a social or email account -- it has its own timers and things
                    # and will attempt the next update when appropriate
                    return

            log.info('Error count too high, or reconnect disabled.')
Esempio n. 9
0
 def dc_SendCompleted(self, session, msg):
     util.call_later(0, self.OnBridgeSent, session, msg)
Esempio n. 10
0
 def Connect(self):
     self.change_reason(self.Reasons.NONE)
     call_later(1.5, self.update)