Exemplo n.º 1
0
        /// <summary>
        /// Send <see cref="EventData"/> to a specific EventHub partition. The targeted partition is pre-determined when this PartitionSender was created.
        /// <para>
        /// There are 3 ways to send to EventHubs, to understand this particular type of send refer to the overload <see cref="SendAsync(EventData)"/>, which is the same type of send and is used to send single <see cref="EventData"/>.
        /// </para>
        /// Sending a batch of <see cref="EventData"/>'s is useful in the following cases:
        /// <para>i.    Efficient send - sending a batch of <see cref="EventData"/> maximizes the overall throughput by optimally using the number of sessions created to EventHubs' service.</para>
        /// <para>ii.   Sending multiple <see cref="EventData"/>'s in a Transaction. To acheive ACID properties, the Gateway Service will forward all <see cref="EventData"/>'s in the batch to a single EventHub partition.</para>
        /// </summary>
        /// <example>
        /// Sample code:
        /// <code>
        /// EventHubClient client = EventHubClient.Create("__connectionString__");
        /// PartitionSender senderToPartitionOne = client.CreatePartitionSender("1");
        ///
        /// while (true)
        /// {
        ///     var events = new List&lt;EventData&gt;();
        ///     for (int count = 1; count &lt; 11; count++)
        ///     {
        ///         var payload = new PayloadEvent(count);
        ///         byte[] payloadBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload));
        ///         var sendEvent = new EventData(payloadBytes);
        ///         var applicationProperties = new Dictionary&lt;string, string&gt;();
        ///         applicationProperties["from"] = "csharpClient";
        ///         sendEvent.Properties = applicationProperties;
        ///         events.Add(sendEvent);
        ///     }
        ///
        ///     await senderToPartitionOne.SendAsync(events);
        ///     Console.WriteLine("Sent Batch... Size: {0}", events.Count);
        ///
        /// }
        /// </code>
        /// </example>
        /// <param name="eventDatas">batch of events to send to EventHub</param>
        /// <returns>a Task that completes when the send operation is done.</returns>
        /// <exception cref="MessageSizeExceededException">the total size of the <see cref="EventData"/> exceeds a pre-defined limit set by the service. Default is 256k bytes.</exception>
        /// <exception cref="EventHubsException">Event Hubs service encountered problems during the operation.</exception>
        public async Task SendAsync(IEnumerable <EventData> eventDatas)
        {
            Guard.ArgumentNotNull(nameof(eventDatas), eventDatas);

            if (eventDatas is EventDataBatch && !string.IsNullOrEmpty(((EventDataBatch)eventDatas).PartitionKey))
            {
                throw Fx.Exception.InvalidOperation(Resources.PartitionSenderInvalidWithPartitionKeyOnBatch);
            }

            await InnerSender.SendAsync(eventDatas, null).ConfigureAwait(false);
        }
Exemplo n.º 2
0
 /// <summary>
 /// Closes and releases resources for the <see cref="PartitionSender"/>.
 /// </summary>
 /// <returns>An asynchronous operation</returns>
 public override async Task CloseAsync()
 {
     EventHubsEventSource.Log.ClientCloseStart(ClientId);
     try
     {
         await InnerSender.CloseAsync().ConfigureAwait(false);
     }
     finally
     {
         EventHubsEventSource.Log.ClientCloseStop(ClientId);
     }
 }
Exemplo n.º 3
0
        /// <summary>
        ///   Closes the producer.
        /// </summary>
        ///
        /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param>
        ///
        /// <returns>A task to be resolved on when the operation has completed.</returns>
        ///
        public virtual async Task CloseAsync(CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();
            IsClosed = true;

            var identifier = GetHashCode().ToString();

            ServiceBusEventSource.Log.ClientCloseStart(typeof(ServiceBusSender), EntityName, identifier);

            // Attempt to close the active transport producers.  In the event that an exception is encountered,
            // it should not impact the attempt to close the connection, assuming ownership.

            var transportProducerException = default(Exception);

            try
            {
                await InnerSender.CloseAsync(cancellationToken).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                ServiceBusEventSource.Log.ClientCloseError(typeof(ServiceBusSender), EntityName, identifier, ex.Message);
                transportProducerException = ex;
            }

            // An exception when closing the connection supersedes one observed when closing the
            // individual transport clients.

            try
            {
                if (OwnsConnection)
                {
                    await Connection.CloseAsync().ConfigureAwait(false);
                }
            }
            catch (Exception ex)
            {
                ServiceBusEventSource.Log.ClientCloseError(typeof(ServiceBusSender), EntityName, identifier, ex.Message);
                throw;
            }
            finally
            {
                ServiceBusEventSource.Log.ClientCloseComplete(typeof(ServiceBusSender), EntityName, identifier);
            }

            // If there was an active exception pending from closing the individual
            // transport producers, surface it now.

            if (transportProducerException != default)
            {
                throw transportProducerException;
            }
        }
Exemplo n.º 4
0
        /// <summary>
        ///   Sends a set of events to the associated Service Bus entity using a batched approach.  If the size of events exceed the
        ///   maximum size of a single batch, an exception will be triggered and the send will fail.
        /// </summary>
        ///
        /// <param name="messages">The set of event data to send.</param>
        /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param>
        ///
        /// <returns>A task to be resolved on when the operation has completed.</returns>
        ///

        /// <seealso cref="SendRangeAsync(IEnumerable{ServiceBusMessage}, CancellationToken)" />
        ///
        internal virtual async Task SendRangeInternal(
            IEnumerable <ServiceBusMessage> messages,
            CancellationToken cancellationToken)
        {
            Argument.AssertNotNull(messages, nameof(messages));

            using DiagnosticScope scope = CreateDiagnosticScope();
            messages = messages.ToList();
            InstrumentMessages(messages);

            try
            {
                await InnerSender.SendAsync(messages, cancellationToken).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
        }
Exemplo n.º 5
0
 public override IExceptionReportSender CreateEmptyClone()
 {
     return(new EmptyBackgroundExceptionReportSender(InnerSender.Clone()));
 }