Beispiel #1
0
 def _on_subscription_error(self, channel, payload):
     logger.error('Error on channel %s: %s', channel, payload)
     subscription = self.subscriptions.get(channel)
     if subscription:
         subscription.on_subscription_error(payload)
         if subscription.deleted():
             del self.subscriptions[channel]
Beispiel #2
0
 def _unsubscribe(self, channel):
     logger.info('unsubscribe from %s', channel)
     old_subscription = self.subscriptions.get(channel)
     if old_subscription:
         logger.info('found old subscription')
         old_subscription.unsubscribe()
     else:
         logger.error("Trying to unsubscribe from unknown channel %s",
                      channel)
Beispiel #3
0
def _lint_args(args):
    if not args:
        return
    if args.get(u'fast_forward') is not None:
        logger.error(
            'Setting "fast_forward" in "args" parameter '
            'is deprecated. Choose appropriate subscription mode instead.')
    if args.get(u'channel') is not None:
        logger.error('Setting "channel" in "args" parameter is not supported')
Beispiel #4
0
 def _perform_state_callback(self, callback_name, *args):
     try:
         logger.info('entering callback %s', callback_name)
         try:
             callback = getattr(self.observer, callback_name)
             callback(*args)
         except AttributeError:
             pass
     except Exception as e:
         logger.error('Caught exception in state callback')
         logger.exception(e)
         self._queue.put(a.Stop())
     finally:
         logger.info('exiting callback %s', callback_name)
Beispiel #5
0
    def _schedule_reconnect(self):
        now = time.time()
        target = self._time_of_last_reconnect +\
            min(
                self.reconnect_interval * (2 ** self._fail_count),
                self.max_reconnect_interval)
        delay = max(target - now, 0)
        logger.error('Reconnecting in %f seconds', delay)

        def reconnect():
            logger.warning('Time to reconnect')
            self._reconnect_timer = None
            self._queue.put(a.Tick())

        self._reconnect_timer = threading.Timer(delay, reconnect)
        self._reconnect_timer.start()
Beispiel #6
0
        def subscribe_callback(ack):
            logger.info('SAck: %s', ack)
            if ack.get('action') == 'rtm/subscribe/ok':
                subscription.on_subscribe_ok(ack)
            elif ack.get('action') == 'rtm/subscribe/error':
                logger.error('Subscription error: %s', ack)

                body = ack.get('body')
                reason = 'Unknown error'
                if body:
                    reason = body.get('reason') or body.get('error')

                subscription.on_subscribe_error(reason)
            else:
                self.on_internal_error(
                    'Unexpected subscribe ack: {0}'.format(ack))
Beispiel #7
0
    def subscribe(self, args=None, observer=None):
        logger.debug('subscribe')

        if self.mode in ['linked', 'cycle']:
            logger.error('Already subscribed or trying to')
            return

        if self._next_observer:
            try:
                self._next_observer.on_deleted()
            except Exception:
                pass

        self._next_observer = observer
        self._next_args = args
        self.mode = 'cycle'

        return self._sm.advance(lambda sm: sm.ModeChange())
Beispiel #8
0
 def _perform_state_callback(self, callback_name, *args):
     if self.observer:
         current_thread_name = threading.current_thread().name
         logger.debug('entering subscription callback %s on %s',
                      callback_name, current_thread_name)
         callback = None
         try:
             callback = getattr(self.observer, callback_name)
         except AttributeError:
             pass
         try:
             if callback:
                 callback(*args)
         except Exception as e:
             logger.error('Caught exception in subscription callback')
             logger.exception(e)
         finally:
             logger.debug('exiting subscription callback %s on %s',
                          callback_name, current_thread_name)
Beispiel #9
0
    def _restore_auth_and_return_true_if_failed(self):
        logger.info('_restore_auth_and_return_true_if_failed')

        if not self.restore_auth_on_reconnect:
            return False

        counter = [len(self._successful_auth_delegates)]
        logger.debug('Restoring %d authentications', counter[0])

        if counter[0] == 0:
            return False

        ready_event = threading.Event()

        def callback(outcome):
            logger.debug('Outcome: %s', outcome)
            if type(outcome) == auth.Done:
                logger.debug('Restored auth')
                counter[0] -= 1
                if counter[0] == 0:
                    ready_event.set()
            else:
                ready_event.set()

        for ad in self._successful_auth_delegates:
            ready_event.clear()
            try:
                self.connection.authenticate(ad, callback)
            except Exception as e:
                logger.exception(e)
            ready_event.wait(10)

        if counter[0] == 0:
            logger.debug('Restoring authentications: done')
            return False
        else:
            logger.error('Failed to restore %d authentications', counter[0])
            return True
Beispiel #10
0
    def process_one_message(self, timeout=1):
        '''Must be called from a single thread
           returns True if the message was Dispose()'''

        try:
            m = self._queue.get(block=True, timeout=timeout)
        except queue.Empty:
            logger.debug('queue is empty')
            return False

        t = type(m)
        logger.info('Begin handling %s', t.__name__)

        if t == a.ChannelData:
            data = m.data
            channel = data['subscription_id']
            subscription = self.subscriptions.get(channel)
            if subscription:
                try:
                    subscription.on_subscription_data(data)
                except Exception as e:
                    logger.error("Exception in on_subscription_data")
                    logger.exception(e)
                    self._queue.put(a.Stop())
            else:
                logger.error('Subscription for %s not found', data)
        elif t == a.Start:
            self._sm.Start()
        elif t == a.Stop:
            self._sm.Stop()
        elif t == a.Dispose:
            self._sm.Dispose()
            self._queue.task_done()
            return True

        elif t == a.Publish:
            if self.is_connected():
                try:
                    self.connection.publish_preserialized_message(
                        m.channel, m.message, m.callback)
                except Exception as e:
                    logger.exception(e)
            else:
                self._offline_queue.append(m)
        elif t == a.Subscribe:
            self._subscribe(m.channel_or_subscription_id,
                            m.mode,
                            m.observer,
                            args=m.args)
        elif t == a.Unsubscribe:
            self._unsubscribe(m.channel_or_subscription_id)
        elif t == a.Read:
            self.connection.read(m.key, m.args, m.callback)
        elif t == a.Write:
            self.connection.write_preserialized_value(m.key, m.value,
                                                      m.callback)
        elif t == a.Delete:
            self.connection.delete(m.key, m.callback)
        elif t == a.Authenticate:
            if self.is_connected():
                self._authenticate(m.auth_delegate, m.callback)
            else:
                self._offline_queue.append(m)
        elif t == a.SolicitedPDU:
            try:
                m.callback(m.payload)
            except Exception as e:
                logger.error("Exception in a solicited PDU callback")
                logger.exception(e)
                self._queue.put(a.Stop())
        elif t == a.Tick:
            self._sm.Tick()

        elif t == a.ConnectingComplete:
            self._sm.ConnectingComplete()
        elif t == a.ConnectingFailed:
            self._sm.ConnectingFailed()
        elif t == a.ConnectionClosed:
            self._sm.ConnectionClosed()
        elif t == a.ChannelError:
            self._sm.ChannelError(m.channel, m.payload)
        elif t == a.InternalError:
            self._sm.InternalError(m.payload)
        elif t == a.FastForward:
            self._perform_state_callback('on_fast_forward', m.channel)
        else:
            logger.error('Unexpected event %s: %s', m, t)

        self._queue.task_done()
        logger.info('Finish handling %s', t.__name__)
        return False
Beispiel #11
0
 def _on_internal_error(self, payload):
     logger.error('RTM internal error: %s', payload)
     self._perform_state_callback('on_internal_error', payload)
Beispiel #12
0
 def on_internal_error(self, message):
     logger.error('Internal error: %s', message)
     self._queue.put(a.InternalError(message))