def test_timeout_reraises_if_no_timeout(self, eventloop): eventloop.side_effect = socket.timeout queue = Mock() with pytest.raises(socket.timeout): list(queue_iterator(queue, timeout=None))
def test_timeout_raises_rpc_exc_on_timeout(self, eventloop): eventloop.side_effect = socket.timeout queue = Mock() with pytest.raises(RpcTimeout): list(queue_iterator(queue, timeout=0.1))
def response_greenthread(): with get_connection() as conn: with conn.channel() as chan: queue = nova.get_topic_queue('test_rpc', 'test', channel=chan) queue.declare() queue_declared.send(True) body, msg = ifirst( queue_iterator(queue, no_ack=True, timeout=2)) msgid, _, _, args = nova.parse_message(body) exchange = nova.get_reply_exchange(msgid) producer = Producer(chan, exchange=exchange, routing_key=msgid) for _ in range(3): msg = dict(result='should ignore this message', failure=None, ending=False) producer.publish(msg) eventlet.sleep(0.1) msg = dict(result=args, failure=None, ending=False) producer.publish(msg) msg = dict(result=None, failure=None, ending=True) producer.publish(msg)
def _poll_messages(self): replies = {} correlation_id = yield while True: try: for body, msg in queue_iterator( self.queue, timeout=self.timeout ): msg_correlation_id = msg.properties.get('correlation_id') if msg_correlation_id not in self.provider._reply_events: _logger.debug( "Unknown correlation id: %s", msg_correlation_id) continue replies[msg_correlation_id] = (body, msg) # Here, and every time we re-enter this coroutine (at the # `yield` statement below) we check if we already have the # data for the new correlation_id before polling for new # messages. while correlation_id in replies: body, msg = replies.pop(correlation_id) self.provider.handle_message(body, msg) correlation_id = yield except RpcTimeout as exc: event = self.provider._reply_events.pop(correlation_id) event.send_exception(exc) # timeout is implemented using socket timeout, so when it # fires the connection is closed, causing the reply queue # to be deleted self._setup_queue() correlation_id = yield except ConnectionError as exc: for event in self.provider._reply_events.values(): rpc_connection_error = RpcConnectionError( 'Disconnected while waiting for reply: %s', exc) event.send_exception(rpc_connection_error) self.provider._reply_events.clear() # In case this was a temporary error, attempt to reconnect. If # we fail, the connection error will bubble. self._setup_queue() correlation_id = yield except KeyboardInterrupt as exc: event = self.provider._reply_events.pop(correlation_id) event.send_exception(exc) # exception may have killed the connection self._setup_queue() correlation_id = yield
def _poll_messages(self): replies = {} correlation_id = yield while True: try: for body, msg in queue_iterator(self.queue, timeout=self.timeout): msg_correlation_id = msg.properties.get('correlation_id') if msg_correlation_id not in self.provider._reply_events: _logger.debug("Unknown correlation id: %s", msg_correlation_id) continue replies[msg_correlation_id] = (body, msg) # Here, and every time we re-enter this coroutine (at the # `yield` statement below) we check if we already have the # data for the new correlation_id before polling for new # messages. while correlation_id in replies: body, msg = replies.pop(correlation_id) self.provider.handle_message(body, msg) correlation_id = yield except RpcTimeout as exc: event = self.provider._reply_events.pop(correlation_id) event.send_exception(exc) # timeout is implemented using socket timeout, so when it # fires the connection is closed, causing the reply queue # to be deleted self._setup_queue() correlation_id = yield except ConnectionError as exc: for event in self.provider._reply_events.values(): rpc_connection_error = RpcConnectionError( 'Disconnected while waiting for reply: %s', exc) event.send_exception(rpc_connection_error) self.provider._reply_events.clear() # In case this was a temporary error, attempt to reconnect. If # we fail, the connection error will bubble. self._setup_queue() correlation_id = yield except KeyboardInterrupt as exc: event = self.provider._reply_events.pop(correlation_id) event.send_exception(exc) # exception may have killed the connection self._setup_queue() correlation_id = yield
def send_rpc(connection, context, exchange, topic, method, args, timeout=None): _log.info('rpc: %s %s.%s', exchange, topic, method) msgid, payload = _create_rpcpayload(context, method, args) with connection.channel() as channel: queue = get_reply_queue(msgid, channel=channel) queue.declare() _send_topic(connection, exchange, topic, payload) iter_ = queue_iterator(queue, timeout=timeout) iter_ = (msg for (_, msg) in iter_) iter_ = responses.iter_rpcresponses(iter_) ret = responses.last(iter_) if ret is not None: return ret.payload['result']
def response_greenthread(): with get_connection() as conn: with conn.channel() as chan: queue = nova.get_topic_queue('test_rpc', 'test', channel=chan) queue.declare() queue_declared.send(True) body, msg = ifirst( queue_iterator(queue, no_ack=True, timeout=2)) msgid, _, _, args = nova.parse_message(body) exchange = nova.get_reply_exchange(msgid) producer = Producer(chan, exchange=exchange, routing_key=msgid) msg = {'result': args, 'failure': None, 'ending': False} producer.publish(msg) msg = {'result': None, 'failure': None, 'ending': True} producer.publish(msg)
def test_no_timeout(self, drain_consumer): drain_consumer.return_value = [(1, 'foo'), (2, 'bar')] queue = Mock() res = list(queue_iterator(queue, timeout=1)) assert res == [(1, 'foo'), (2, 'bar')]