/// <summary> /// Asynchronously send a single message to a Kafka topic/partition. /// </summary> /// <param name="topicPartition"> /// The topic/partition to produce the message to. /// </param> /// <param name="message"> /// The message to produce. /// </param> /// <param name="cancellationToken"> /// A cancellation token that can be used to abort this request. /// </param> /// <returns> /// A Task which will complete with a delivery report corresponding to /// the produce request, or an exception if an error occured. /// </returns> public Task <DeliveryResult <TKey, TValue> > ProduceAsync( TopicPartition topicPartition, Message <TKey, TValue> message, CancellationToken cancellationToken = default(CancellationToken)) { var keyBytes = (keySerializer != null) ? keySerializer.Serialize(message.Key, true, message, topicPartition) : taskKeySerializer.SerializeAsync(message.Key, true, message, topicPartition) .ConfigureAwait(continueOnCapturedContext: false) .GetAwaiter() .GetResult(); var valBytes = (valueSerializer != null) ? valueSerializer.Serialize(message.Value, false, message, topicPartition) : taskValueSerializer.SerializeAsync(message.Value, false, message, topicPartition) .ConfigureAwait(continueOnCapturedContext: false) .GetAwaiter() .GetResult(); if (this.enableDeliveryReports) { var handler = new TypedTaskDeliveryHandlerShim <TKey, TValue>(topicPartition.Topic, enableDeliveryReportKey ? message.Key : default(TKey), enableDeliveryReportValue ? message.Value : default(TValue)); cancellationToken.Register(() => handler.TrySetException(new TaskCanceledException())); base.Produce( topicPartition.Topic, valBytes, 0, valBytes == null ? 0 : valBytes.Length, keyBytes, 0, keyBytes == null ? 0 : keyBytes.Length, message.Timestamp, topicPartition.Partition, message.Headers, handler); return(handler.Task); } else { base.Produce( topicPartition.Topic, valBytes, 0, valBytes == null ? 0 : valBytes.Length, keyBytes, 0, keyBytes == null ? 0 : keyBytes.Length, message.Timestamp, topicPartition.Partition, message.Headers, null); var result = new DeliveryResult <TKey, TValue> { TopicPartitionOffset = new TopicPartitionOffset(topicPartition, Offset.Invalid), Message = message }; return(Task.FromResult(result)); } }
public void HandleDeliveryReport(DeliveryReport <Null, Null> deliveryReport) { if (CancellationTokenRegistration != null) { CancellationTokenRegistration.Dispose(); } if (deliveryReport == null) { #if NET45 System.Threading.Tasks.Task.Run(() => TrySetResult(null)); #else TrySetResult(null); #endif return; } var dr = new DeliveryResult <TKey, TValue> { TopicPartitionOffset = deliveryReport.TopicPartitionOffset, Status = deliveryReport.Status, Message = new Message <TKey, TValue> { Key = Key, Value = Value, Timestamp = deliveryReport.Message.Timestamp, Headers = deliveryReport.Message.Headers } }; // topic is cached in this object, not set in the deliveryReport to avoid the // cost of marshalling it. dr.Topic = Topic; #if NET45 if (deliveryReport.Error.IsError) { System.Threading.Tasks.Task.Run(() => SetException(new ProduceException <TKey, TValue>(deliveryReport.Error, dr))); } else { System.Threading.Tasks.Task.Run(() => TrySetResult(dr)); } #else if (deliveryReport.Error.IsError) { TrySetException(new ProduceException <TKey, TValue>(deliveryReport.Error, dr)); } else { TrySetResult(dr); } #endif }
/// <summary> /// Refer to <see cref="Confluent.Kafka.IProducer{TKey,TValue}.ProduceAsync(TopicPartition, Message{TKey, TValue})" /> /// </summary> public async Task <DeliveryResult <TKey, TValue> > ProduceAsync( TopicPartition topicPartition, Message <TKey, TValue> message) { byte[] keyBytes; try { keyBytes = (keySerializer != null) ? keySerializer(message.Key) : await asyncKeySerializer.SerializeAsync(message.Key, new SerializationContext(MessageComponentType.Key, topicPartition.Topic)); } catch (Exception ex) { throw new ProduceException <TKey, TValue>( new Error(ErrorCode.Local_KeySerialization), new DeliveryResult <TKey, TValue> { Message = message, TopicPartitionOffset = new TopicPartitionOffset(topicPartition, Offset.Unset) }, ex); } byte[] valBytes; try { valBytes = (valueSerializer != null) ? valueSerializer(message.Value) : await asyncValueSerializer.SerializeAsync(message.Value, new SerializationContext(MessageComponentType.Value, topicPartition.Topic)); } catch (Exception ex) { throw new ProduceException <TKey, TValue>( new Error(ErrorCode.Local_ValueSerialization), new DeliveryResult <TKey, TValue> { Message = message, TopicPartitionOffset = new TopicPartitionOffset(topicPartition, Offset.Unset) }, ex); } try { if (enableDeliveryReports) { var handler = new TypedTaskDeliveryHandlerShim <TKey, TValue>( topicPartition.Topic, enableDeliveryReportKey ? message.Key : default(TKey), enableDeliveryReportValue ? message.Value : default(TValue)); ProduceImpl( topicPartition.Topic, valBytes, 0, valBytes == null ? 0 : valBytes.Length, keyBytes, 0, keyBytes == null ? 0 : keyBytes.Length, message.Timestamp, topicPartition.Partition, message.Headers, handler); return(await handler.Task); } else { ProduceImpl( topicPartition.Topic, valBytes, 0, valBytes == null ? 0 : valBytes.Length, keyBytes, 0, keyBytes == null ? 0 : keyBytes.Length, message.Timestamp, topicPartition.Partition, message.Headers, null); var result = new DeliveryResult <TKey, TValue> { TopicPartitionOffset = new TopicPartitionOffset(topicPartition, Offset.Unset), Message = message }; return(result); } } catch (KafkaException ex) { throw new ProduceException <TKey, TValue>( ex.Error, new DeliveryResult <TKey, TValue> { Message = message, TopicPartitionOffset = new TopicPartitionOffset(topicPartition, Offset.Unset) }); } }
/// <inheritdoc/> public async Task <DeliveryResult <TKey, TValue> > ProduceAsync( TopicPartition topicPartition, Message <TKey, TValue> message, CancellationToken cancellationToken) { Headers headers = message.Headers ?? new Headers(); byte[] keyBytes; try { keyBytes = (keySerializer != null) ? keySerializer.Serialize(message.Key, new SerializationContext(MessageComponentType.Key, topicPartition.Topic, headers)) : await asyncKeySerializer.SerializeAsync(message.Key, new SerializationContext(MessageComponentType.Key, topicPartition.Topic, headers)).ConfigureAwait(false); } catch (Exception ex) { throw new ProduceException <TKey, TValue>( new Error(ErrorCode.Local_KeySerialization), new DeliveryResult <TKey, TValue> { Message = message, TopicPartitionOffset = new TopicPartitionOffset(topicPartition, Offset.Unset) }, ex); } byte[] valBytes; try { valBytes = (valueSerializer != null) ? valueSerializer.Serialize(message.Value, new SerializationContext(MessageComponentType.Value, topicPartition.Topic, headers)) : await asyncValueSerializer.SerializeAsync(message.Value, new SerializationContext(MessageComponentType.Value, topicPartition.Topic, headers)).ConfigureAwait(false); } catch (Exception ex) { throw new ProduceException <TKey, TValue>( new Error(ErrorCode.Local_ValueSerialization), new DeliveryResult <TKey, TValue> { Message = message, TopicPartitionOffset = new TopicPartitionOffset(topicPartition, Offset.Unset) }, ex); } try { if (enableDeliveryReports) { var handler = new TypedTaskDeliveryHandlerShim( topicPartition.Topic, enableDeliveryReportKey ? message.Key : default(TKey), enableDeliveryReportValue ? message.Value : default(TValue)); if (cancellationToken != null && cancellationToken.CanBeCanceled) { handler.CancellationTokenRegistration = cancellationToken.Register(() => handler.TrySetCanceled()); } ProduceImpl( topicPartition.Topic, valBytes, 0, valBytes == null ? 0 : valBytes.Length, keyBytes, 0, keyBytes == null ? 0 : keyBytes.Length, message.Timestamp, topicPartition.Partition, headers, handler); return(await handler.Task.ConfigureAwait(false)); } else { ProduceImpl( topicPartition.Topic, valBytes, 0, valBytes == null ? 0 : valBytes.Length, keyBytes, 0, keyBytes == null ? 0 : keyBytes.Length, message.Timestamp, topicPartition.Partition, headers, null); var result = new DeliveryResult <TKey, TValue> { TopicPartitionOffset = new TopicPartitionOffset(topicPartition, Offset.Unset), Message = message }; return(result); } } catch (KafkaException ex) { throw new ProduceException <TKey, TValue>( ex.Error, new DeliveryResult <TKey, TValue> { Message = message, TopicPartitionOffset = new TopicPartitionOffset(topicPartition, Offset.Unset) }); } }
/// <summary> /// Asynchronously send a single message to a Kafka topic/partition. /// </summary> /// <param name="topicPartition"> /// The topic/partition to produce the message to. /// </param> /// <param name="message"> /// The message to produce. /// </param> /// <returns> /// A Task which will complete with a delivery report corresponding to /// the produce request, or an exception if an error occured. /// </returns> public Task <DeliveryResult <TKey, TValue> > ProduceAsync( TopicPartition topicPartition, Message <TKey, TValue> message) { byte[] keyBytes; try { keyBytes = (keySerializer != null) ? keySerializer.Serialize(message.Key, new SerializationContext(MessageComponentType.Key, topicPartition.Topic)) : asyncKeySerializer.SerializeAsync(message.Key, new SerializationContext(MessageComponentType.Key, topicPartition.Topic)) .ConfigureAwait(continueOnCapturedContext: false) .GetAwaiter() .GetResult(); } catch (Exception exception) { throw new ProduceException <TKey, TValue>( new Error(ErrorCode.Local_KeySerialization), new DeliveryResult <TKey, TValue> { Message = message, TopicPartitionOffset = new TopicPartitionOffset(topicPartition, Offset.Invalid) }, exception); } byte[] valBytes; try { valBytes = (valueSerializer != null) ? valueSerializer.Serialize(message.Value, new SerializationContext(MessageComponentType.Value, topicPartition.Topic)) : asyncValueSerializer.SerializeAsync(message.Value, new SerializationContext(MessageComponentType.Value, topicPartition.Topic)) .ConfigureAwait(continueOnCapturedContext: false) .GetAwaiter() .GetResult(); } catch (Exception exception) { throw new ProduceException <TKey, TValue>( new Error(ErrorCode.Local_ValueSerialization), new DeliveryResult <TKey, TValue> { Message = message, TopicPartitionOffset = new TopicPartitionOffset(topicPartition, Offset.Invalid) }, exception); } try { if (enableDeliveryReports) { var handler = new TypedTaskDeliveryHandlerShim <TKey, TValue>( topicPartition.Topic, enableDeliveryReportKey ? message.Key : default(TKey), enableDeliveryReportValue ? message.Value : default(TValue)); ProduceImpl( topicPartition.Topic, valBytes, 0, valBytes == null ? 0 : valBytes.Length, keyBytes, 0, keyBytes == null ? 0 : keyBytes.Length, message.Timestamp, topicPartition.Partition, message.Headers, handler); return(handler.Task); } else { ProduceImpl( topicPartition.Topic, valBytes, 0, valBytes == null ? 0 : valBytes.Length, keyBytes, 0, keyBytes == null ? 0 : keyBytes.Length, message.Timestamp, topicPartition.Partition, message.Headers, null); var result = new DeliveryResult <TKey, TValue> { TopicPartitionOffset = new TopicPartitionOffset(topicPartition, Offset.Invalid), Message = message }; return(Task.FromResult(result)); } } catch (KafkaException ex) { throw new ProduceException <TKey, TValue>( ex.Error, new DeliveryResult <TKey, TValue> { Message = message, TopicPartitionOffset = new TopicPartitionOffset(topicPartition, Offset.Invalid) }); } // want other exceptions: ArgumentException, InvalidOperationException to propagate up. }
/// <summary> /// Initialize a new instance of ProduceException based on /// an existing Error value. /// </summary> /// <param name="error"> /// The error associated with the delivery report. /// </param> /// <param name="deliveryResult"> /// The delivery result associated with the produce request. /// </param> public ProduceException(Error error, DeliveryResult <TKey, TValue> deliveryResult) : base(error) { DeliveryResult = deliveryResult; }
/// <summary> /// Initialize a new instance of ProduceException based on /// an existing Error value. /// </summary> /// <param name="error"> /// The error associated with the delivery result. /// </param> /// <param name="deliveryResult"> /// The delivery result associated with the produce request. /// </param> /// <param name="innerException"> /// The exception instance that caused this exception. /// </param> public ProduceException(Error error, DeliveryResult <TKey, TValue> deliveryResult, Exception innerException) : base(error, innerException) { DeliveryResult = deliveryResult; }