public override Task SendAsync(IEnumerable <EventData> events, SendEventOptions sendOptions, CancellationToken cancellationToken) { SendCalledWith = (events, sendOptions); return(Task.CompletedTask); }
public async Task ProducerManagesConcurrencyWhenPublishingEvents() { await using (EventHubScope scope = await EventHubScope.CreateAsync(1)) { var connectionString = EventHubsTestEnvironment.Instance.BuildConnectionStringForEventHub(scope.EventHubName); var options = new EventHubProducerClientOptions { EnableIdempotentPartitions = true }; await using var producer = new EventHubProducerClient(connectionString, options); var cancellationSource = new CancellationTokenSource(); cancellationSource.CancelAfter(EventHubsTestEnvironment.Instance.TestExecutionTimeLimit); var partition = (await producer.GetPartitionIdsAsync(cancellationSource.Token)).First(); var sendOptions = new SendEventOptions { PartitionId = partition }; async Task sendEvents(int delayMilliseconds) { await Task.Delay(delayMilliseconds); await producer.SendAsync(EventGenerator.CreateEvents(2), sendOptions, cancellationSource.Token); } var pendingSends = Task.WhenAll( sendEvents(100), sendEvents(50), sendEvents(0) ); Assert.That(async() => await pendingSends, Throws.Nothing); } }
public async Task ProducerUpdatesPropertiesAfterPublishingEvents() { await using (EventHubScope scope = await EventHubScope.CreateAsync(1)) { var connectionString = EventHubsTestEnvironment.Instance.BuildConnectionStringForEventHub(scope.EventHubName); var options = new EventHubProducerClientOptions { EnableIdempotentPartitions = true }; await using var producer = new EventHubProducerClient(connectionString, options); var cancellationSource = new CancellationTokenSource(); cancellationSource.CancelAfter(EventHubsTestEnvironment.Instance.TestExecutionTimeLimit); var partition = (await producer.GetPartitionIdsAsync(cancellationSource.Token)).First(); var initialPartitionProperties = await producer.GetPartitionPublishingPropertiesAsync(partition); var sendOptions = new SendEventOptions { PartitionId = partition }; var events = EventGenerator.CreateEvents(10).ToArray(); await producer.SendAsync(events, sendOptions, cancellationSource.Token); var updatedPartitionProperties = await producer.GetPartitionPublishingPropertiesAsync(partition); Assert.That(updatedPartitionProperties.IsIdempotentPublishingEnabled, Is.True, "Idempotent publishing should be enabled."); Assert.That(updatedPartitionProperties.ProducerGroupId, Is.EqualTo(initialPartitionProperties.ProducerGroupId), "The producer group identifier should not have changed."); Assert.That(updatedPartitionProperties.OwnerLevel, Is.EqualTo(initialPartitionProperties.OwnerLevel), "The owner level should not have changed."); Assert.That(updatedPartitionProperties.LastPublishedSequenceNumber, Is.GreaterThan(initialPartitionProperties.LastPublishedSequenceNumber), "The last published sequence number should have increased."); } }
public async Task ProducerInitializesPropertiesWhenPublishing() { await using (EventHubScope scope = await EventHubScope.CreateAsync(1)) { var connectionString = EventHubsTestEnvironment.Instance.BuildConnectionStringForEventHub(scope.EventHubName); var options = new IdempotentProducerOptions { EnableIdempotentPartitions = true }; await using var producer = new IdempotentProducer(connectionString, options); var cancellationSource = new CancellationTokenSource(); cancellationSource.CancelAfter(EventHubsTestEnvironment.Instance.TestExecutionTimeLimit); var partition = (await producer.GetPartitionIdsAsync(cancellationSource.Token)).First(); var sendOptions = new SendEventOptions { PartitionId = partition }; var events = EventGenerator.CreateEvents(10).ToArray(); await producer.SendAsync(events, sendOptions, cancellationSource.Token); var partitionProperties = await producer.GetPartitionPublishingPropertiesAsync(partition); Assert.That(partitionProperties, Is.Not.Null, "The properties should have been created."); Assert.That(partitionProperties.IsIdempotentPublishingEnabled, Is.True, "Idempotent publishing should be enabled."); Assert.That(partitionProperties.ProducerGroupId.HasValue, Is.True, "The producer group identifier should have a value."); Assert.That(partitionProperties.OwnerLevel.HasValue, Is.True, "The owner level should have a value."); Assert.That(partitionProperties.LastPublishedSequenceNumber.HasValue, Is.True, "The last published sequence number should have a value."); } }
static async Task Main(string[] args) { var secrets = Secrets.LoadFromFile(); // Sending event to a stream // Here the StreamGuid will be encoded as the PartitionKey, and the namespace as a property of the event await using (var client = new EventHubProducerClient(secrets.EventHubConnectionString, Constants.EHPath)) { var key = Guid.NewGuid().ToString(); var options = new SendEventOptions { PartitionKey = Guid.NewGuid().ToString() }; Console.WriteLine($"Sending event to StreamId: [{key}, {Constants.StreamNamespace}]"); for (int i = 0; i < 30; i++) { Console.WriteLine($"Sending '{i}'"); var evt = new EventData(JsonSerializer.SerializeToUtf8Bytes(i)); evt.Properties["StreamNamespace"] = Constants.StreamNamespace; await client.SendAsync(new[] { evt }, options); await Task.Delay(TimeSpan.FromSeconds(1)); } } Console.WriteLine("Done!"); }
public async Task SendEnumerableUsesThePartitionKey() { var expectedPartitionKey = "some key"; var options = new SendEventOptions { PartitionKey = expectedPartitionKey }; var retryPolicy = new BasicRetryPolicy(new EventHubsRetryOptions { TryTimeout = TimeSpan.FromSeconds(17) }); var producer = new Mock <AmqpProducer>("aHub", null, Mock.Of <AmqpConnectionScope>(), new AmqpMessageConverter(), retryPolicy) { CallBase = true }; producer .Protected() .Setup <Task>("SendAsync", ItExpr.IsAny <Func <AmqpMessage> >(), ItExpr.Is <string>(value => value == expectedPartitionKey), ItExpr.IsAny <CancellationToken>()) .Returns(Task.CompletedTask) .Verifiable(); await producer.Object.SendAsync(new[] { new EventData(new byte[] { 0x15 }) }, options, CancellationToken.None); producer.VerifyAll(); }
public async Task SendAsync(IEnumerable <EventData> eventData, string partitionKey, CancellationToken token) { var options = new SendEventOptions(); options.PartitionKey = partitionKey; await _client.SendAsync(eventData, options, token); }
public async Task ProducerCanPublishEvents(EventHubsTransportType transportType) { await using (EventHubScope scope = await EventHubScope.CreateAsync(1)) { var connectionString = EventHubsTestEnvironment.Instance.BuildConnectionStringForEventHub(scope.EventHubName); var options = new EventHubProducerClientOptions { EnableIdempotentPartitions = true, ConnectionOptions = new EventHubConnectionOptions { TransportType = transportType } }; await using var producer = new EventHubProducerClient(connectionString, options); var cancellationSource = new CancellationTokenSource(); cancellationSource.CancelAfter(EventHubsTestEnvironment.Instance.TestExecutionTimeLimit); var partition = (await producer.GetPartitionIdsAsync(cancellationSource.Token)).First(); var sendOptions = new SendEventOptions { PartitionId = partition }; Assert.That(async() => await producer.SendAsync(EventGenerator.CreateEvents(2), sendOptions, cancellationSource.Token), Throws.Nothing, "The first publishing operation was not successful."); Assert.That(async() => await producer.SendAsync(EventGenerator.CreateEvents(2), sendOptions, cancellationSource.Token), Throws.Nothing, "The second publishing operation was not successful."); } }
/// <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="sendOptions">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> /// public override async Task SendAsync(IReadOnlyCollection <EventData> events, SendEventOptions sendOptions, CancellationToken cancellationToken) { Argument.AssertNotNull(events, nameof(events)); Argument.AssertNotClosed(_closed, nameof(AmqpProducer)); Argument.AssertNotClosed(ConnectionScope.IsDisposed, nameof(EventHubConnection)); var partitionKey = sendOptions?.PartitionKey; var messages = new AmqpMessage[events.Count]; var index = 0; foreach (var eventData in events) { messages[index] = MessageConverter.CreateMessageFromEvent(eventData, partitionKey); ++index; } try { await SendAsync(messages, partitionKey, cancellationToken).ConfigureAwait(false); } finally { foreach (var message in messages) { message.Dispose(); } } }
public IEnumerator SendOnly() { Logger.LogDelegate += Utils.Log; var f = false; var c = Utils.NewClient("ct6"); c.Connect().OnSuccess(_ => { return(c.CreateRoom()); }).Unwrap().OnSuccess(_ => { Task.Run(async() => { var count = 6; while (count > 0 && !f) { var options = new SendEventOptions { ReceiverGroup = ReceiverGroup.Others }; await c.SendEvent(5, null, options); Thread.Sleep(5000); } }); Task.Delay(30000).OnSuccess(__ => { Debug.Log("delay 30s done"); f = true; }); }); while (!f) { yield return(null); } c.Close(); }
public Task SendAsync(IEnumerable <MessagingEventData> batch, string partitionKey) { var sendOptions = new SendEventOptions { PartitionKey = partitionKey }; return(this.inner.SendAsync(batch, sendOptions)); }
public override async Task SetupAsync() { await base.SetupAsync(); _sendOptions = await CreateSendOptions(s_producer).ConfigureAwait(false); // Publish an empty event to force the connection and link to be established. await s_producer.SendAsync(new[] { new EventData(Array.Empty <byte>()) }, _sendOptions).ConfigureAwait(false); }
/// <summary> /// Verifies property accessors for the <see cref="EventDataBatch" /> /// constructor. /// </summary> /// public void ConstructorUpdatesState() { var sendOptions = new SendEventOptions(); var mockBatch = new MockTransportBatch(); var batch = new EventDataBatch(new MockTransportBatch(), null); Assert.That(batch.SendOptions, Is.SameAs(sendOptions), "The send options should have been set."); Assert.That(GetInnerBatch(batch), Is.SameAs(mockBatch), "The inner transport batch should have been set."); }
/// <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="sendOptions">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> /// public override async Task SendAsync(IEnumerable <EventData> events, SendEventOptions sendOptions, CancellationToken cancellationToken) { Argument.AssertNotNull(events, nameof(events)); Argument.AssertNotClosed(_closed, nameof(AmqpProducer)); AmqpMessage messageFactory() => MessageConverter.CreateBatchFromEvents(events, sendOptions?.PartitionKey); await SendAsync(messageFactory, sendOptions?.PartitionKey, cancellationToken).ConfigureAwait(false); }
public void SendForASpecificPartitionDoesNotAllowAPartitionHashKey() { var sendOptions = new SendEventOptions { PartitionKey = "testKey", PartitionId = "1" }; var events = new[] { new EventData(new byte[] { 0x44, 0x66, 0x88 }) }; var transportProducer = new ObservableTransportProducerMock(); var producer = new EventHubProducerClient(new MockConnection(() => transportProducer)); Assert.That(async() => await producer.SendAsync(events, sendOptions), Throws.InvalidOperationException); }
public void SendAllowsAPartitionHashKey() { var sendOptions = new SendEventOptions { PartitionKey = "testKey" }; var events = new[] { new EventData(new byte[] { 0x44, 0x66, 0x88 }) }; var transportProducer = new ObservableTransportProducerMock(); var producer = new EventHubProducerClient(new MockConnection(() => transportProducer)); Assert.That(async() => await producer.SendAsync(events, sendOptions), Throws.Nothing); }
public async Task SendInvokesTheTransportProducer() { var events = new EventData[0]; var options = new SendEventOptions(); var transportProducer = new ObservableTransportProducerMock(); var producer = new EventHubProducerClient(new MockConnection(() => transportProducer)); await producer.SendAsync(events, options); (IEnumerable <EventData> calledWithEvents, SendEventOptions calledWithOptions) = transportProducer.SendCalledWith; Assert.That(calledWithEvents, Is.EquivalentTo(events), "The events should contain same elements."); Assert.That(calledWithOptions, Is.SameAs(options), "The options should be the same instance"); }
/// <summary> /// Performs the tasks needed to initialize and set up the environment for the test scenario. /// When multiple instances are run in parallel, the setup will take place once, prior to the /// execution of the first test instance. /// </summary> /// public async override Task GlobalSetupAsync() { await base.GlobalSetupAsync().ConfigureAwait(false); s_scope = await EventHubScope.CreateAsync(4).ConfigureAwait(false); s_producer = new EventHubProducerClient(TestEnvironment.EventHubsConnectionString, s_scope.EventHubName); s_sendOptions = await CreateSendOptions(s_producer).ConfigureAwait(false); s_eventBody = EventGenerator.CreateRandomBody(Options.Size); // Publish an empty event to force the connection and link to be established. await s_producer.SendAsync(new[] { new EventData(Array.Empty <byte>()) }, s_sendOptions).ConfigureAwait(false); }
public void CloneProducesACopy() { var options = new SendEventOptions { PartitionId = "0", PartitionKey = "some_partition_123" }; var clone = options.Clone(); Assert.That(clone, Is.Not.Null, "The clone should not be null."); Assert.That(clone, Is.TypeOf <SendEventOptions>(), "The clone should be a SendEventOptions instance."); Assert.That(clone, Is.Not.SameAs(options), "The clone should not the same reference as the options."); Assert.That(clone.PartitionId, Is.EqualTo(options.PartitionId), "The partition identifier of the clone should match."); Assert.That(clone.PartitionKey, Is.EqualTo(options.PartitionKey), "The partition key of the clone should match."); }
public async Task FixtureSetUp() { // Create a set of consumer groups to ensure that there aren't too // many concurrent readers when tests are executed concurrently. var testCount = GetType() .GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(method => method.GetCustomAttribute(typeof(TestAttribute)) != null) .Count(); var readersPerGroup = 5; var consumerGroupCount = Math.Ceiling((double)testCount / readersPerGroup); var consumerGroups = Enumerable.Range(0, (int)consumerGroupCount).Select(index => $"group{ index }"); foreach (var group in consumerGroups) { for (var index = 0; index < readersPerGroup; ++index) { _availableConsumerGroups.Enqueue(group); } } _scope = await EventHubScope.CreateAsync(2, consumerGroups); // Because some snippets assume events are present in the first partition, publish // a small set to satisfy the assumption. using var cancellationSource = new CancellationTokenSource(); cancellationSource.CancelAfter(EventHubsTestEnvironment.Instance.TestExecutionTimeLimit); await using var producer = new EventHubProducerClient(EventHubsTestEnvironment.Instance.EventHubsConnectionString, _scope.EventHubName); var toPublish = Enumerable .Range(0, 5) .Select(index => new EventData(new BinaryData($"Event: { index }"))); var partition = (await producer.GetPartitionIdsAsync(cancellationSource.Token)).First(); var options = new SendEventOptions { PartitionId = partition }; await producer.SendAsync(toPublish, options); }
public IEnumerator CustomEventWithTargetIds() { Logger.LogDelegate += Utils.Log; var f = false; var roomName = "ce1_r"; var c0 = Utils.NewClient("ce1_0"); var c1 = Utils.NewClient("ce1_1"); c0.Connect().OnSuccess(_ => { return(c0.CreateRoom(roomName)); }).Unwrap().OnSuccess(_ => { c0.OnCustomEvent += (eventId, eventData, senderId) => { Assert.AreEqual(eventId, 2); Assert.AreEqual(eventData["name"] as string, "aaa"); Assert.AreEqual(int.Parse(eventData["count"].ToString()), 100); f = true; }; return(c1.Connect()); }).Unwrap().OnSuccess(_ => { return(c1.JoinRoom(roomName)); }).Unwrap().OnSuccess(_ => { var eventData = new Dictionary <string, object> { { "name", "aaa" }, { "count", 100 }, }; var options = new SendEventOptions { TargetActorIds = new List <int> { 1, 2 } }; return(c1.SendEvent(2, eventData, options)); }).Unwrap().OnSuccess(_ => { Debug.Log("send event done"); }); while (!f) { yield return(null); } c0.Close(); c1.Close(); }
public async Task ProducerCanPublishEventsAfterAnException() { await using (EventHubScope scope = await EventHubScope.CreateAsync(1)) { var cancellationSource = new CancellationTokenSource(); cancellationSource.CancelAfter(EventHubsTestEnvironment.Instance.TestExecutionTimeLimit); var connectionString = EventHubsTestEnvironment.Instance.BuildConnectionStringForEventHub(scope.EventHubName); var options = new EventHubProducerClientOptions { EnableIdempotentPartitions = true }; await using var producer = new EventHubProducerClient(connectionString, options); var partition = (await producer.GetPartitionIdsAsync()).First(); var sendOptions = new SendEventOptions { PartitionId = partition }; // Publish some events to validate that the initial publish works. Assert.That(async() => await producer.SendAsync(EventGenerator.CreateSmallEvents(2), sendOptions, cancellationSource.Token), Throws.Nothing, "The first publishing operation was not successful."); // Publish an event too large to succeed; this will force the producer to deal with an exception, which should // update idempotent state. using var batch = await producer.CreateBatchAsync(cancellationSource.Token); var producerId = (await producer.GetPartitionPublishingPropertiesAsync(partition, cancellationSource.Token)).ProducerGroupId; var badEvent = new EventData(EventGenerator.CreateRandomBody(batch.MaximumSizeInBytes + 1000)); Assert.That(async() => await producer.SendAsync(new[] { badEvent }, sendOptions, cancellationSource.Token), Throws.InstanceOf <EventHubsException>(), "The attempt to publish a too-large event should fail."); // Publish a second set of events; this will prove that the producer recovered from the exception. Assert.That(async() => await producer.SendAsync(EventGenerator.CreateSmallEvents(3), sendOptions, cancellationSource.Token), Throws.Nothing, "The second publishing operation was not successful."); var newProducerId = (await producer.GetPartitionPublishingPropertiesAsync(partition, cancellationSource.Token)).ProducerGroupId; Assert.That(newProducerId, Is.Not.Null, "The producer group identifier should have a value."); Assert.That(newProducerId, Is.Not.EqualTo(producerId), "The producer group identifier should have been updated after the exception."); } }
public async Task ProducerSequencesEvents() { await using (EventHubScope scope = await EventHubScope.CreateAsync(2)) { var connectionString = EventHubsTestEnvironment.Instance.BuildConnectionStringForEventHub(scope.EventHubName); var options = new EventHubProducerClientOptions { EnableIdempotentPartitions = true }; await using var producer = new EventHubProducerClient(connectionString, options); var cancellationSource = new CancellationTokenSource(); cancellationSource.CancelAfter(EventHubsTestEnvironment.Instance.TestExecutionTimeLimit); var partition = (await producer.GetPartitionIdsAsync(cancellationSource.Token)).Last(); var sendOptions = new SendEventOptions { PartitionId = partition }; var partitionProperties = await producer.GetPartitionPublishingPropertiesAsync(partition); var eventSequenceNumber = partitionProperties.LastPublishedSequenceNumber; var events = EventGenerator.CreateEvents(10).ToArray(); Assert.That(events.Any(item => item.PublishedSequenceNumber.HasValue), Is.False, "Events should start out as unpublished with no sequence number."); await producer.SendAsync(events, sendOptions, cancellationSource.Token); Assert.That(events.All(item => item.PublishedSequenceNumber.HasValue), Is.True, "Events should be sequenced after publishing."); foreach (var item in events) { Assert.That(item.PublishedSequenceNumber, Is.EqualTo(++eventSequenceNumber), $"The sequence numbers should be contiguous. Event { eventSequenceNumber } was out of order."); } } }
// Use this for initialization async void Start() { // 设置 SDK 日志委托 LeanCloud.Play.Logger.LogDelegate = (level, log) => { if (level == LogLevel.Debug) { Debug.LogFormat("[DEBUG] {0}", log); } else if (level == LogLevel.Warn) { Debug.LogFormat("[WARN] {0}", log); } else if (level == LogLevel.Error) { Debug.LogFormat("[ERROR] {0}", log); } }; // App Id var APP_ID = "FQr8l8LLvdxIwhMHN77sNluX-9Nh9j0Va"; // App Key var APP_KEY = "MJSm46Uu6LjF5eNmqfbuUmt6"; // 这里使用随机数作为 userId var random = new System.Random(); var randId = string.Format("{0}", random.Next(10000000)); idText.text = string.Format("Id: {0}", randId); // 初始化 client = new Client(APP_ID, APP_KEY, randId); await client.Connect(); Debug.Log("connected"); // 根据当前时间(时,分)生成房间名称 var now = System.DateTime.Now; var roomName = string.Format("{0}_{1}", now.Hour, now.Minute); await client.JoinOrCreateRoom(roomName); Debug.Log("joined room"); // 注册新玩家加入房间事件 client.OnPlayerRoomJoined += (newPlayer) => { Debug.LogFormat("new player: {0}", newPlayer.UserId); if (client.Player.IsMaster) { // 获取房间内玩家列表 var playerList = client.Room.PlayerList; for (int i = 0; i < playerList.Count; i++) { var player = playerList[i]; var props = new PlayObject(); // 判断如果是房主,则设置 10 分,否则设置 5 分 if (player.IsMaster) { props.Add("point", 10); } else { props.Add("point", 5); } player.SetCustomProperties(props); } var data = new PlayObject { { "winnerId", client.Room.Master.ActorId } }; var opts = new SendEventOptions { ReceiverGroup = ReceiverGroup.All }; client.SendEvent(GAME_OVER_EVENT, data, opts); } }; // 注册「玩家属性变更」事件 client.OnPlayerCustomPropertiesChanged += (player, changedProps) => { // 判断如果玩家是自己,则做 UI 显示 if (player.IsLocal) { // 得到玩家的分数 long point = player.CustomProperties.GetInt("point"); Debug.LogFormat("{0} : {1}", player.UserId, point); scoreText.text = string.Format("Score: {0}", point); } }; // 注册自定义事件 client.OnCustomEvent += (eventId, eventData, senderId) => { if (eventId == GAME_OVER_EVENT) { // 得到胜利者 Id int winnerId = eventData.GetInt("winnerId"); // 如果胜利者是自己,则显示胜利 UI;否则显示失败 UI if (client.Player.ActorId == winnerId) { Debug.Log("win"); resultText.text = "Win"; } else { Debug.Log("lose"); resultText.text = "Lose"; } client.Close(); } }; }
extern private static bool SendEventWithVersion(string eventName, object parameters, int ver, SendEventOptions sendEventOptions = SendEventOptions.kAppendNone);
extern private static bool SendEvent(string eventName, object parameters, SendEventOptions sendEventOptions = SendEventOptions.kAppendNone);
public async Task Produce <T>(T message, IPipe <EventHubSendContext <T> > pipe, CancellationToken cancellationToken) where T : class { LogContext.SetCurrentIfNull(_context.LogContext); var context = new EventHubMessageSendContext <T>(message, cancellationToken) { Serializer = _context.Serializer }; if (_consumeContext != null) { context.TransferConsumeContextHeaders(_consumeContext); } context.DestinationAddress = _topicAddress; await _context.Send(context).ConfigureAwait(false); if (pipe.IsNotEmpty()) { await pipe.Send(context).ConfigureAwait(false); } context.SourceAddress ??= _context.HostAddress; context.ConversationId ??= NewId.NextGuid(); var options = new SendEventOptions { PartitionId = context.PartitionId, PartitionKey = context.PartitionKey }; StartedActivity?activity = LogContext.IfEnabled(OperationName.Transport.Send)?.StartSendActivity(context, (nameof(context.PartitionId), options.PartitionId), (nameof(context.PartitionKey), options.PartitionKey)); try { if (_context.SendObservers.Count > 0) { await _context.SendObservers.PreSend(context).ConfigureAwait(false); } var eventData = new EventData(context.Body); eventData.Properties.Set(context.Headers); await _context.Produce(new[] { eventData }, options, context.CancellationToken).ConfigureAwait(false); context.LogSent(); activity.AddSendContextHeadersPostSend(context); if (_context.SendObservers.Count > 0) { await _context.SendObservers.PostSend(context).ConfigureAwait(false); } } catch (Exception exception) { context.LogFaulted(exception); if (_context.SendObservers.Count > 0) { await _context.SendObservers.SendFault(context, exception).ConfigureAwait(false); } throw; } finally { activity?.Stop(); } }
public async Task Send(ProducerContext context) { LogContext.SetCurrentIfNull(_context.LogContext); var sendContext = new EventHubMessageSendContext <T>(_message, _cancellationToken) { Serializer = context.Serializer, DestinationAddress = _context.EndpointAddress }; await _context.SendPipe.Send(sendContext).ConfigureAwait(false); if (_pipe.IsNotEmpty()) { await _pipe.Send(sendContext).ConfigureAwait(false); } sendContext.SourceAddress ??= _context.HostAddress; sendContext.ConversationId ??= NewId.NextGuid(); var options = new SendEventOptions { PartitionId = sendContext.PartitionId, PartitionKey = sendContext.PartitionKey }; StartedActivity?activity = LogContext.IfEnabled(OperationName.Transport.Send)?.StartSendActivity(sendContext, (nameof(sendContext.PartitionId), options.PartitionId), (nameof(sendContext.PartitionKey), options.PartitionKey)); try { if (_context.SendObservers.Count > 0) { await _context.SendObservers.PreSend(sendContext).ConfigureAwait(false); } var eventData = new EventData(sendContext.Body); eventData.Properties.Set(sendContext.Headers); await context.Produce(new[] { eventData }, options, sendContext.CancellationToken).ConfigureAwait(false); sendContext.LogSent(); activity.AddSendContextHeadersPostSend(sendContext); if (_context.SendObservers.Count > 0) { await _context.SendObservers.PostSend(sendContext).ConfigureAwait(false); } } catch (Exception exception) { sendContext.LogFaulted(exception); if (_context.SendObservers.Count > 0) { await _context.SendObservers.SendFault(sendContext, exception).ConfigureAwait(false); } throw; } finally { activity?.Stop(); } }
/// <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="sendOptions">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> /// public abstract Task SendAsync(IEnumerable <EventData> events, SendEventOptions sendOptions, CancellationToken cancellationToken);
public Task Produce(IEnumerable <EventData> eventData, SendEventOptions options, CancellationToken cancellationToken) { return(_producerClient.SendAsync(eventData, options, cancellationToken)); }