示例#1
0
        public void Send <K, V>(string topic, K key, V value, Headers headers, long timestamp, ISerDes <K> keySerializer, ISerDes <V> valueSerializer)
        {
            var k = key != null?keySerializer.Serialize(key, new SerializationContext(MessageComponentType.Key, topic, headers)) : null;

            var v = value != null?valueSerializer.Serialize(value, new SerializationContext(MessageComponentType.Value, topic, headers)) : null;

            try
            {
                producer?.Produce(
                    topic,
                    new Message <byte[], byte[]> {
                    Key = k, Value = v
                },
                    (report) =>
                {
                    if (report.Error.IsError)
                    {
                        StringBuilder sb = new StringBuilder();
                        sb.AppendLine($"{logPrefix}Error encountered sending record to topic {topic} for task {id} due to:");
                        sb.AppendLine($"{logPrefix}Error Code : {report.Error.Code.ToString()}");
                        sb.AppendLine($"{logPrefix}Message : {report.Error.Reason}");

                        if (IsFatalError(report))
                        {
                            sb.AppendLine($"{logPrefix}Written offsets would not be recorded and no more records would be sent since this is a fatal error.");
                            log.Error(sb.ToString());
                            throw new StreamsException(sb.ToString());
                        }
                        else if (IsRecoverableError(report))
                        {
                            sb.AppendLine($"{logPrefix}Written offsets would not be recorded and no more records would be sent since the producer is fenced, indicating the task may be migrated out");
                            log.Error(sb.ToString());
                            throw new TaskMigratedException(sb.ToString());
                        }
                        else
                        {
                            if (configuration.ProductionExceptionHandler(report) == ExceptionHandlerResponse.FAIL)
                            {
                                sb.AppendLine($"{logPrefix}Exception handler choose to FAIL the processing, no more records would be sent.");
                                log.Error(sb.ToString());
                                throw new ProductionException(sb.ToString());
                            }
                            else
                            {
                                sb.AppendLine($"{logPrefix}Exception handler choose to CONTINUE processing in spite of this error but written offsets would not be recorded.");
                                log.Error(sb.ToString());
                            }
                        }
                    }
                    else if (report.Status == PersistenceStatus.NotPersisted || report.Status == PersistenceStatus.PossiblyPersisted)
                    {
                        log.Warn($"{logPrefix}Record not persisted or possibly persisted: (timestamp {report.Message.Timestamp.UnixTimestampMs}) topic=[{topic}] partition=[{report.Partition}] offset=[{report.Offset}]. May config Retry configuration, depends your use case.");
                    }
                    else if (report.Status == PersistenceStatus.Persisted)
                    {
                        log.Debug($"{logPrefix}Record persisted: (timestamp {report.Message.Timestamp.UnixTimestampMs}) topic=[{topic}] partition=[{report.Partition}] offset=[{report.Offset}]");
                    }
                });
            }catch (ProduceException <byte[], byte[]> produceException)
            {
                if (IsRecoverableError(produceException.Error))
                {
                    throw new TaskMigratedException($"Producer got fenced trying to send a record [{logPrefix}] : {produceException.Message}");
                }
                else
                {
                    throw new StreamsException($"Error encountered trying to send record to topic {topic} [{logPrefix}] : {produceException.Message}");
                }
            }
        }