Esempio n. 1
0
 /// <summary>
 ///   Sends an event to the associated Event Hub using a batched approach.  If the size of the event exceeds the
 ///   maximum size of a single batch, an exception will be triggered and the send will fail.
 /// </summary>
 ///
 /// <param name="eventData">The event data to send.</param>
 /// <param name="options">The set of options to consider when sending this batch.</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="SendAsync(EventData, CancellationToken)" />
 /// <seealso cref="SendAsync(IEnumerable{EventData}, CancellationToken)" />
 /// <seealso cref="SendAsync(IEnumerable{EventData}, SendEventOptions, CancellationToken)" />
 /// <seealso cref="SendAsync(EventDataBatch, CancellationToken)" />
 ///
 internal virtual Task SendAsync(EventData eventData,
                                 SendEventOptions options,
                                 CancellationToken cancellationToken = default)
 {
     Argument.AssertNotNull(eventData, nameof(eventData));
     return(SendAsync(new[] { eventData }, options, cancellationToken));
 }
        /// <summary>
        ///   Initializes a new instance of the <see cref="EventDataBatch"/> class.
        /// </summary>
        ///
        /// <param name="transportBatch">The  transport-specific batch responsible for performing the batch operations.</param>
        /// <param name="sendOptions">The set of options that should be used when publishing the batch.</param>
        ///
        /// <remarks>
        ///   As an internal type, this class performs only basic sanity checks against its arguments.  It
        ///   is assumed that callers are trusted and have performed deep validation.
        ///
        ///   Any parameters passed are assumed to be owned by this instance and safe to mutate or dispose;
        ///   creation of clones or otherwise protecting the parameters is assumed to be the purview of the
        ///   caller.
        /// </remarks>
        ///
        internal EventDataBatch(TransportEventBatch transportBatch,
                                SendEventOptions sendOptions)
        {
            Argument.AssertNotNull(transportBatch, nameof(transportBatch));
            Argument.AssertNotNull(sendOptions, nameof(sendOptions));

            InnerBatch  = transportBatch;
            SendOptions = sendOptions;
        }
Esempio n. 3
0
        /// <summary>
        ///   Sends a set of events to the associated Event Hub 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="events">The set of event data to send.</param>
        /// <param name="options">The set of options to consider when sending this batch.</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="SendAsync(EventData, CancellationToken)" />
        /// <seealso cref="SendAsync(EventData, SendEventOptions, CancellationToken)" />
        /// <seealso cref="SendAsync(IEnumerable{EventData}, CancellationToken)" />
        /// <seealso cref="SendAsync(EventDataBatch, CancellationToken)" />
        ///
        internal virtual async Task SendAsync(IEnumerable <EventData> events,
                                              SendEventOptions options,
                                              CancellationToken cancellationToken = default)
        {
            options ??= DefaultSendOptions;

            Argument.AssertNotNull(events, nameof(events));
            AssertSinglePartitionReference(options.PartitionId, options.PartitionKey);

            // Determine the transport producer to delegate the send operation to.  Because sending to a specific
            // partition requires a dedicated client, use (or create) that client if a partition was specified.  Otherwise
            // the default gateway producer can be used to request automatic routing from the Event Hubs service gateway.

            TransportProducer activeProducer;

            if (string.IsNullOrEmpty(options.PartitionId))
            {
                activeProducer = EventHubProducer;
            }
            else
            {
                // This assertion is intended as an additional check, not as a guarantee.  There still exists a benign
                // race condition where a transport producer may be created after the client has been closed; in this case
                // the transport producer will be force-closed with the associated connection or, worst case, will close once
                // its idle timeout period elapses.

                Argument.AssertNotClosed(IsClosed, nameof(EventHubProducerClient));
                activeProducer = PartitionProducers.GetOrAdd(options.PartitionId, id => Connection.CreateTransportProducer(id, RetryPolicy));
            }

            using DiagnosticScope scope = CreateDiagnosticScope();

            events = events.ToList();
            InstrumentMessages(events);

            try
            {
                await activeProducer.SendAsync(events, options, cancellationToken).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
        }