Callback invoker to sink all thrown exceptions (#74)

This commit is contained in:
Alex Damian
2018-06-01 19:35:56 -04:00
committed by Matias Fontanini
parent 15fdab6943
commit 9714bec5bf
9 changed files with 180 additions and 66 deletions

View File

@@ -33,6 +33,7 @@
#include <chrono>
#include <functional>
#include <thread>
#include <string>
#include "../consumer.h"
#include "backoff_performer.h"
@@ -118,6 +119,7 @@ public:
*/
void commit(const TopicPartitionList& topic_partitions);
private:
// Return true to abort and false to continue committing
template <typename T>
bool do_commit(const T& object) {
try {
@@ -131,13 +133,11 @@ private:
if (ex.get_error() == RD_KAFKA_RESP_ERR__NO_OFFSET) {
return true;
}
// If there's a callback and it returns false for this message, abort
if (callback_ && !callback_(ex.get_error())) {
return true;
}
// If there's a callback and it returns false for this message, abort.
// Otherwise keep committing.
CallbackInvoker<ErrorCallback> callback("backoff committer", callback_, &consumer_);
return callback && !callback(ex.get_error());
}
// In any other case, we failed. Keep committing
return false;
}
Consumer& consumer_;

View File

@@ -364,9 +364,9 @@ void BufferedProducer<BufferType>::flush() {
produce_message(flush_queue.front());
}
catch (const HandleException& ex) {
if (flush_failure_callback_ &&
flush_failure_callback_(flush_queue.front(), ex.get_error())) {
// retry again later
// If we have a flush failure callback and it returns true, we retry producing this message later
CallbackInvoker<FlushFailureCallback> callback("flush failure", flush_failure_callback_, &producer_);
if (callback && callback(flush_queue.front(), ex.get_error())) {
do_add_message(std::move(flush_queue.front()), MessagePriority::Low, false);
}
}
@@ -519,19 +519,18 @@ void BufferedProducer<BufferType>::on_delivery_report(const Message& message) {
--pending_acks_;
assert(pending_acks_ != (size_t)-1); // Prevent underflow
// We should produce this message again if it has an error and we either don't have a
// produce failure callback or we have one but it returns true
bool should_produce = message.get_error() &&
(!produce_failure_callback_ || produce_failure_callback_(message));
if (should_produce) {
// Re-enqueue for later retransmission with higher priority (i.e. front of the queue)
do_add_message(Builder(message), MessagePriority::High, false);
if (message.get_error()) {
// We should produce this message again if we don't have a produce failure callback
// or we have one but it returns true
CallbackInvoker<ProduceFailureCallback> callback("produce failure", produce_failure_callback_, &producer_);
if (!callback || callback(message)) {
// Re-enqueue for later retransmission with higher priority (i.e. front of the queue)
do_add_message(Builder(message), MessagePriority::High, false);
}
}
else {
// Successful delivery
if (produce_success_callback_) {
produce_success_callback_(message);
}
CallbackInvoker<ProduceSuccessCallback>("delivery success", produce_success_callback_, &producer_)(message);
// Increment the total successful transmissions
++total_messages_produced_;
}