def close(self, exception=None): # type:(Exception) -> None """ Close down the handler. If the handler has already closed, this will be a no op. An optional exception can be passed in to indicate that the handler was shutdown due to error. :param exception: An optional exception if the handler is closing due to an error. :type exception: Exception Example: .. literalinclude:: ../examples/test_examples_eventhub.py :start-after: [START eventhub_client_receiver_close] :end-before: [END eventhub_client_receiver_close] :language: python :dedent: 4 :caption: Close down the handler. """ if self.messages_iter: self.messages_iter.close() self.messages_iter = None self.running = False if self.error: return if isinstance(exception, errors.LinkRedirect): self.redirected = exception elif isinstance(exception, EventHubError): self.error = exception elif exception: self.error = EventHubError(str(exception)) else: self.error = EventHubError("This receive handler is now closed.") self._handler.close()
def receive(self, max_batch_size=None, timeout=None): # type:(int, float) -> List[EventData] """ Receive events from the EventHub. :param max_batch_size: Receive a batch of events. Batch size will be up to the maximum specified, but will return as soon as service returns no new events. If combined with a timeout and no events are retrieve before the time, the result will be empty. If no batch size is supplied, the prefetch size will be the maximum. :type max_batch_size: int :param timeout: The maximum wait time to build up the requested message count for the batch. If not specified, the default wait time specified when the consumer was created will be used. :type timeout: float :rtype: list[~azure.eventhub.common.EventData] :raises: ~azure.eventhub.AuthenticationError, ~azure.eventhub.ConnectError, ~azure.eventhub.ConnectionLostError, ~azure.eventhub.EventHubError Example: .. literalinclude:: ../examples/test_examples_eventhub.py :start-after: [START eventhub_client_sync_receive] :end-before: [END eventhub_client_sync_receive] :language: python :dedent: 4 :caption: Receive events from the EventHub. """ self._check_closed() self._open() max_batch_size = min( self.client.config.max_batch_size, self.prefetch) if max_batch_size is None else max_batch_size timeout = self.client.config.receive_timeout if timeout is None else timeout data_batch = [] # type: List[EventData] max_retries = self.client.config.max_retries connecting_count = 0 while True: connecting_count += 1 try: timeout_ms = 1000 * timeout if timeout else 0 message_batch = self._handler.receive_message_batch( max_batch_size=max_batch_size - (len(data_batch) if data_batch else 0), timeout=timeout_ms) for message in message_batch: event_data = EventData(message=message) self.offset = EventPosition(event_data.offset) data_batch.append(event_data) return data_batch except errors.AuthenticationException as auth_error: if connecting_count < max_retries: log.info( "EventHubConsumer disconnected due to token error. Attempting reconnect." ) self._reconnect() else: log.info( "EventHubConsumer authentication failed. Shutting down." ) error = AuthenticationError(str(auth_error), auth_error) self.close(auth_error) raise error except (errors.LinkDetach, errors.ConnectionClose) as shutdown: if shutdown.action.retry and self.auto_reconnect: log.info( "EventHubConsumer detached. Attempting reconnect.") self._reconnect() else: log.info("EventHubConsumer detached. Shutting down.") error = ConnectionLostError(str(shutdown), shutdown) self.close(exception=error) raise error except errors.MessageHandlerError as shutdown: if connecting_count < max_retries: log.info( "EventHubConsumer detached. Attempting reconnect.") self._reconnect() else: log.info("EventHubConsumer detached. Shutting down.") error = ConnectionLostError(str(shutdown), shutdown) self.close(error) raise error except errors.AMQPConnectionError as shutdown: if connecting_count < max_retries: log.info( "EventHubConsumer connection lost. Attempting reconnect." ) self._reconnect() else: log.info( "EventHubConsumer connection lost. Shutting down.") error = ConnectionLostError(str(shutdown), shutdown) self.close(error) raise error except compat.TimeoutException as shutdown: if connecting_count < max_retries: log.info( "EventHubConsumer timed out receiving event data. Attempting reconnect." ) self._reconnect() else: log.info("EventHubConsumer timed out. Shutting down.") self.close(shutdown) raise ConnectionLostError(str(shutdown), shutdown) except KeyboardInterrupt: log.info("EventHubConsumer stops due to keyboard interrupt") self.close() raise except Exception as e: log.error("Unexpected error occurred (%r). Shutting down.", e) error = EventHubError("Receive failed: {}".format(e), e) self.close(exception=error) raise error
def _check_closed(self): if self.error: raise EventHubError( "This consumer has been closed. Please create a new consumer to receive event data.", self.error)
def _build_connection(self, is_reconnect=False): """ :param is_reconnect: True - trying to reconnect after fail to connect or a connection is lost. False - the 1st time to connect :return: True - connected. False - not connected """ # pylint: disable=protected-access if is_reconnect: alt_creds = { "username": self.client._auth_config.get("iot_username"), "password": self.client._auth_config.get("iot_password") } self._handler.close() source = Source(self.source) if self.offset is not None: source.set_filter(self.offset._selector()) self._handler = ReceiveClient( source, auth=self.client.get_auth(**alt_creds), debug=self.client.config.network_tracing, prefetch=self.prefetch, link_properties=self.properties, timeout=self.timeout, error_policy=self.retry_policy, keep_alive_interval=self.keep_alive, client_name=self.name, properties=self.client._create_properties( self.client.config.user_agent)) # pylint: disable=protected-access self.messages_iter = None try: self._handler.open() while not self._handler.client_ready(): time.sleep(0.05) return True except errors.AuthenticationException as shutdown: if is_reconnect: log.info( "EventHubConsumer couldn't authenticate. Shutting down. (%r)", shutdown) error = AuthenticationError(str(shutdown), shutdown) self.close(exception=error) raise error else: log.info( "EventHubConsumer couldn't authenticate. Attempting reconnect." ) return False except errors.LinkRedirect as redirect: self._redirect(redirect) return True except (errors.LinkDetach, errors.ConnectionClose) as shutdown: if shutdown.action.retry: log.info("EventHubConsumer detached. Attempting reconnect.") return False else: log.info("EventHubConsumer detached. Shutting down.") error = ConnectError(str(shutdown), shutdown) self.close(exception=error) raise error except errors.MessageHandlerError as shutdown: if is_reconnect: log.info("EventHubConsumer detached. Shutting down.") error = ConnectError(str(shutdown), shutdown) self.close(exception=error) raise error else: log.info("EventHubConsumer detached. Attempting reconnect.") return False except errors.AMQPConnectionError as shutdown: if is_reconnect: log.info( "EventHubConsumer connection error (%r). Shutting down.", shutdown) error = AuthenticationError(str(shutdown), shutdown) self.close(exception=error) raise error else: log.info( "EventHubConsumer couldn't authenticate. Attempting reconnect." ) return False except compat.TimeoutException as shutdown: if is_reconnect: log.info( "EventHubConsumer authentication timed out. Shutting down." ) error = AuthenticationError(str(shutdown), shutdown) self.close(exception=error) raise error else: log.info( "EventHubConsumer authentication timed out. Attempting reconnect." ) return False except Exception as e: log.error( "Unexpected error occurred when building connection (%r). Shutting down.", e) error = EventHubError( "Unexpected error occurred when building connection", e) self.close(exception=error) raise error
def __next__(self): self._open() max_retries = self.client.config.max_retries connecting_count = 0 while True: connecting_count += 1 try: if not self.messages_iter: self.messages_iter = self._handler.receive_messages_iter() message = next(self.messages_iter) event_data = EventData(message=message) self.offset = EventPosition(event_data.offset, inclusive=False) return event_data except errors.AuthenticationException as auth_error: if connecting_count < max_retries: log.info( "EventHubConsumer disconnected due to token error. Attempting reconnect." ) self._reconnect() else: log.info( "EventHubConsumer authentication failed. Shutting down." ) error = AuthenticationError(str(auth_error), auth_error) self.close(auth_error) raise error except (errors.LinkDetach, errors.ConnectionClose) as shutdown: if shutdown.action.retry and self.auto_reconnect: log.info( "EventHubConsumer detached. Attempting reconnect.") self._reconnect() else: log.info("EventHubConsumer detached. Shutting down.") error = ConnectionLostError(str(shutdown), shutdown) self.close(exception=error) raise error except errors.MessageHandlerError as shutdown: if connecting_count < max_retries: log.info( "EventHubConsumer detached. Attempting reconnect.") self._reconnect() else: log.info("EventHubConsumer detached. Shutting down.") error = ConnectionLostError(str(shutdown), shutdown) self.close(error) raise error except errors.AMQPConnectionError as shutdown: if connecting_count < max_retries: log.info( "EventHubConsumer connection lost. Attempting reconnect." ) self._reconnect() else: log.info( "EventHubConsumer connection lost. Shutting down.") error = ConnectionLostError(str(shutdown), shutdown) self.close(error) raise error except compat.TimeoutException as shutdown: if connecting_count < max_retries: log.info( "EventHubConsumer timed out receiving event data. Attempting reconnect." ) self._reconnect() else: log.info("EventHubConsumer timed out. Shutting down.") self.close(shutdown) raise ConnectionLostError(str(shutdown), shutdown) except StopIteration: raise except KeyboardInterrupt: log.info("EventHubConsumer stops due to keyboard interrupt") self.close() raise except Exception as e: log.error("Unexpected error occurred (%r). Shutting down.", e) error = EventHubError("Receive failed: {}".format(e), e) self.close(exception=error) raise error
def _check_closed(self): if self._closed: raise EventHubError( "{} has been closed. Please create a new one to handle event data." .format(self._name))
def _check_closed(self): if self.error: raise EventHubError( "This producer has been closed. Please create a new producer to send event data.", self.error)
def _send_event_data(self): self._open() max_retries = self.client.config.max_retries connecting_count = 0 while True: connecting_count += 1 try: if self.unsent_events: self._handler.queue_message(*self.unsent_events) self._handler.wait() self.unsent_events = self._handler.pending_messages if self._outcome != constants.MessageSendResult.Ok: EventHubProducer._error(self._outcome, self._condition) return except (errors.MessageAccepted, errors.MessageAlreadySettled, errors.MessageModified, errors.MessageRejected, errors.MessageReleased, errors.MessageContentTooLarge) as msg_error: raise EventDataError(str(msg_error), msg_error) except errors.MessageException as failed: log.error("Send event data error (%r)", failed) error = EventDataSendError(str(failed), failed) self.close(exception=error) raise error except errors.AuthenticationException as auth_error: if connecting_count < max_retries: log.info( "EventHubProducer disconnected due to token error. Attempting reconnect." ) self._reconnect() else: log.info( "EventHubProducer authentication failed. Shutting down." ) error = AuthenticationError(str(auth_error), auth_error) self.close(auth_error) raise error except (errors.LinkDetach, errors.ConnectionClose) as shutdown: if shutdown.action.retry: log.info( "EventHubProducer detached. Attempting reconnect.") self._reconnect() else: log.info("EventHubProducer detached. Shutting down.") error = ConnectionLostError(str(shutdown), shutdown) self.close(exception=error) raise error except errors.MessageHandlerError as shutdown: if connecting_count < max_retries: log.info( "EventHubProducer detached. Attempting reconnect.") self._reconnect() else: log.info("EventHubProducer detached. Shutting down.") error = ConnectionLostError(str(shutdown), shutdown) self.close(error) raise error except errors.AMQPConnectionError as shutdown: if connecting_count < max_retries: log.info( "EventHubProducer connection lost. Attempting reconnect." ) self._reconnect() else: log.info( "EventHubProducer connection lost. Shutting down.") error = ConnectionLostError(str(shutdown), shutdown) self.close(error) raise error except compat.TimeoutException as shutdown: if connecting_count < max_retries: log.info( "EventHubProducer timed out sending event data. Attempting reconnect." ) self._reconnect() else: log.info("EventHubProducer timed out. Shutting down.") self.close(shutdown) raise ConnectionLostError(str(shutdown), shutdown) except Exception as e: log.info("Unexpected error occurred (%r). Shutting down.", e) error = EventHubError("Send failed: {}".format(e), e) self.close(exception=error) raise error
def _build_connection(self, is_reconnect=False): """ :param is_reconnect: True - trying to reconnect after fail to connect or a connection is lost. False - the 1st time to connect :return: True - connected. False - not connected """ # pylint: disable=protected-access if is_reconnect: self._handler.close() self._handler = SendClient( self.target, auth=self.client.get_auth(), debug=self.client.config.network_tracing, msg_timeout=self.timeout, error_policy=self.retry_policy, keep_alive_interval=self.keep_alive, client_name=self.name, properties=self.client._create_properties( self.client.config.user_agent)) try: self._handler.open() while not self._handler.client_ready(): time.sleep(0.05) return True except errors.AuthenticationException as shutdown: if is_reconnect: log.info( "EventHubProducer couldn't authenticate. Shutting down. (%r)", shutdown) error = AuthenticationError(str(shutdown), shutdown) self.close(exception=error) raise error else: log.info( "EventHubProducer couldn't authenticate. Attempting reconnect." ) return False except (errors.LinkDetach, errors.ConnectionClose) as shutdown: if shutdown.action.retry: log.info("EventHubProducer detached. Attempting reconnect.") return False else: log.info("EventHubProducer detached. Shutting down.") error = ConnectError(str(shutdown), shutdown) self.close(exception=error) raise error except errors.MessageHandlerError as shutdown: if is_reconnect: log.info("EventHubProducer detached. Shutting down.") error = ConnectError(str(shutdown), shutdown) self.close(exception=error) raise error else: log.info("EventHubProducer detached. Attempting reconnect.") return False except errors.AMQPConnectionError as shutdown: if is_reconnect: log.info( "EventHubProducer connection error (%r). Shutting down.", shutdown) error = AuthenticationError(str(shutdown), shutdown) self.close(exception=error) raise error else: log.info( "EventHubProducer couldn't authenticate. Attempting reconnect." ) return False except compat.TimeoutException as shutdown: if is_reconnect: log.info( "EventHubProducer authentication timed out. Shutting down." ) error = AuthenticationError(str(shutdown), shutdown) self.close(exception=error) raise error else: log.info( "EventHubProducer authentication timed out. Attempting reconnect." ) return False except Exception as e: log.info( "Unexpected error occurred when building connection (%r). Shutting down.", e) error = EventHubError( "Unexpected error occurred when building connection", e) self.close(exception=error) raise error