-
Notifications
You must be signed in to change notification settings - Fork 3.3k
create_batch feature implementation #6256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
ba7d811
28ad2f3
3d638fc
9779be0
d0a51bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,26 +13,28 @@ | |
| from uamqp import compat | ||
| from uamqp import SendClient | ||
|
|
||
| from azure.eventhub.common import EventData, _BatchSendEventData | ||
| from azure.eventhub.common import EventData, _BatchSendEventData, EventDataBatch | ||
| from azure.eventhub.error import EventHubError, ConnectError, \ | ||
| AuthenticationError, EventDataError, EventDataSendError, ConnectionLostError, _error_handler | ||
|
|
||
| log = logging.getLogger(__name__) | ||
|
|
||
|
|
||
|
|
||
|
|
||
| class EventHubProducer(object): | ||
| """ | ||
| A producer responsible for transmitting EventData to a specific Event Hub, | ||
| grouped together in batches. Depending on the options specified at creation, the producer may | ||
| be created to allow event data to be automatically routed to an available partition or specific | ||
| to a partition. | ||
| grouped together in batches. Depending on the options specified at creation, the producer may | ||
| be created to allow event data to be automatically routed to an available partition or specific | ||
| to a partition. | ||
|
|
||
| """ | ||
|
|
||
| def __init__(self, client, target, partition=None, send_timeout=60, keep_alive=None, auto_reconnect=True): | ||
| """ | ||
| Instantiate an EventHubProducer. EventHubProducer should be instantiated by calling the `create_producer` method | ||
| in EventHubClient. | ||
| in EventHubClient. | ||
|
|
||
| :param client: The parent EventHubClient. | ||
| :type client: ~azure.eventhub.client.EventHubClient. | ||
|
|
@@ -51,6 +53,7 @@ def __init__(self, client, target, partition=None, send_timeout=60, keep_alive=N | |
| Default value is `True`. | ||
| :type auto_reconnect: bool | ||
| """ | ||
| self._max_message_size_on_link = None | ||
| self.running = False | ||
| self.client = client | ||
| self.target = target | ||
|
|
@@ -109,6 +112,10 @@ def _open(self): | |
| self._connect() | ||
| self.running = True | ||
|
|
||
| self._max_message_size_on_link = self._handler.message_handler._link.peer_max_message_size if\ | ||
| self._handler.message_handler._link.peer_max_message_size\ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Under what circumstances there is no peer_max_message_size? When the link is not open?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure about it. It seems that the peer_max_message_size should always be returned back from service side as it's part of the link negotiation in amqp protocol. |
||
| else constants.MAX_MESSAGE_LENGTH_BYTES | ||
|
|
||
| def _connect(self): | ||
| connected = self._build_connection() | ||
| if not connected: | ||
|
|
@@ -298,6 +305,23 @@ def _error(outcome, condition): | |
| if outcome != constants.MessageSendResult.Ok: | ||
| raise condition | ||
|
|
||
| def create_batch(self, max_message_size=None, partition_key=None): | ||
| """ | ||
| Create an EventDataBatch object with max message size being max_message_size. | ||
| The max_message_size should be no greater than the max allowed message size defined by the service side. | ||
| :param max_message_size: | ||
| :param partition_key: | ||
| :return: | ||
| """ | ||
| if not self._max_message_size_on_link: | ||
| self._open() | ||
|
|
||
| if max_message_size and max_message_size > self._max_message_size_on_link: | ||
| raise EventDataError('Max message size: {} is too large, acceptable max batch size is: {} bytes.' | ||
| .format(max_message_size, self._max_message_size_on_link)) | ||
|
|
||
| return EventDataBatch(max_message_size if max_message_size else self._max_message_size_on_link, partition_key) | ||
|
|
||
| def send(self, event_data, partition_key=None): | ||
| # type:(Union[EventData, Union[List[EventData], Iterator[EventData], Generator[EventData]]], Union[str, bytes]) -> None | ||
| """ | ||
|
|
@@ -307,7 +331,8 @@ def send(self, event_data, partition_key=None): | |
| :param event_data: The event to be sent. It can be an EventData object, or iterable of EventData objects | ||
| :type event_data: ~azure.eventhub.common.EventData, Iterator, Generator, list | ||
| :param partition_key: With the given partition_key, event data will land to | ||
| a particular partition of the Event Hub decided by the service. | ||
| a particular partition of the Event Hub decided by the service. partition_key | ||
| will be omitted if event_data is of type ~azure.eventhub.EventDataBatch. | ||
| :type partition_key: str | ||
| :raises: ~azure.eventhub.AuthenticationError, ~azure.eventhub.ConnectError, ~azure.eventhub.ConnectionLostError, | ||
| ~azure.eventhub.EventDataError, ~azure.eventhub.EventDataSendError, ~azure.eventhub.EventHubError | ||
|
|
@@ -326,14 +351,17 @@ def send(self, event_data, partition_key=None): | |
| """ | ||
| self._check_closed() | ||
| if isinstance(event_data, EventData): | ||
| if partition_key: | ||
| event_data._set_partition_key(partition_key) | ||
| event_data._set_partition_key(partition_key) # pylint: disable=protected-access | ||
| wrapper_event_data = event_data | ||
| else: | ||
| event_data_with_pk = self._set_partition_key(event_data, partition_key) | ||
| wrapper_event_data = _BatchSendEventData( | ||
| event_data_with_pk, | ||
| partition_key=partition_key) if partition_key else _BatchSendEventData(event_data) | ||
| if isinstance(event_data, EventDataBatch): | ||
| wrapper_event_data = event_data | ||
| else: | ||
| if partition_key: | ||
| event_data_with_pk = self._set_partition_key(event_data, partition_key) | ||
| wrapper_event_data = _BatchSendEventData(event_data_with_pk, partition_key=partition_key) | ||
| else: | ||
| wrapper_event_data = _BatchSendEventData(event_data) | ||
| wrapper_event_data.message.on_send_complete = self._on_outcome | ||
| self.unsent_events = [wrapper_event_data.message] | ||
| self._send_event_data() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it better to have one class instead of two with inheritance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea. I've done that.
Take a look at the new design.