mirror of
https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka.git
synced 2025-11-01 11:07:56 +00:00
Replaced termination callback with throwing exception
This commit is contained in:
@@ -7,20 +7,17 @@ set(CPPKAFKA_VERSION_MINOR 2)
|
|||||||
set(CPPKAFKA_VERSION "${CPPKAFKA_VERSION_MAJOR}.${CPPKAFKA_VERSION_MINOR}")
|
set(CPPKAFKA_VERSION "${CPPKAFKA_VERSION_MAJOR}.${CPPKAFKA_VERSION_MINOR}")
|
||||||
set(RDKAFKA_MIN_VERSION 0x00090400)
|
set(RDKAFKA_MIN_VERSION 0x00090400)
|
||||||
|
|
||||||
if (NOT CMAKE_CXX_FLAGS)
|
if(MSVC)
|
||||||
# Set default compile flags for the project
|
|
||||||
if(MSVC)
|
|
||||||
# Don't always use Wall, since VC's /Wall is ridiculously verbose.
|
# Don't always use Wall, since VC's /Wall is ridiculously verbose.
|
||||||
set(CMAKE_CXX_FLAGS "/W3")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3")
|
||||||
|
|
||||||
# Disable VC secure checks, since these are not really issues
|
# Disable VC secure checks, since these are not really issues
|
||||||
add_definitions("-D_CRT_SECURE_NO_WARNINGS=1")
|
add_definitions("-D_CRT_SECURE_NO_WARNINGS=1")
|
||||||
add_definitions("-D_SCL_SECURE_NO_WARNINGS=1")
|
add_definitions("-D_SCL_SECURE_NO_WARNINGS=1")
|
||||||
add_definitions("-DNOGDI=1")
|
add_definitions("-DNOGDI=1")
|
||||||
add_definitions("-DNOMINMAX=1")
|
add_definitions("-DNOMINMAX=1")
|
||||||
else()
|
else()
|
||||||
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ namespace cppkafka {
|
|||||||
*/
|
*/
|
||||||
class CPPKAFKA_API Error {
|
class CPPKAFKA_API Error {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructs an error object with RD_KAFKA_RESP_ERR_NO_ERROR
|
||||||
|
*/
|
||||||
|
Error() = default;
|
||||||
/**
|
/**
|
||||||
* Constructs an error object
|
* Constructs an error object
|
||||||
*/
|
*/
|
||||||
@@ -77,7 +81,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
CPPKAFKA_API friend std::ostream& operator<<(std::ostream& output, const Error& rhs);
|
CPPKAFKA_API friend std::ostream& operator<<(std::ostream& output, const Error& rhs);
|
||||||
private:
|
private:
|
||||||
rd_kafka_resp_err_t error_;
|
rd_kafka_resp_err_t error_{RD_KAFKA_RESP_ERR_NO_ERROR};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // cppkafka
|
} // cppkafka
|
||||||
|
|||||||
@@ -100,10 +100,18 @@ public:
|
|||||||
*/
|
*/
|
||||||
void set_error_callback(ErrorCallback callback);
|
void set_error_callback(ErrorCallback callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Commits the current partition assignment synchronously
|
||||||
|
*
|
||||||
|
* This will call Consumer::commit() until either the message is successfully
|
||||||
|
* committed or the error callback returns false (if any is set).
|
||||||
|
*/
|
||||||
|
void commit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Commits the given message synchronously
|
* \brief Commits the given message synchronously
|
||||||
*
|
*
|
||||||
* This will call Consumer::commit until either the message is successfully
|
* This will call Consumer::commit(msg) until either the message is successfully
|
||||||
* committed or the error callback returns false (if any is set).
|
* committed or the error callback returns false (if any is set).
|
||||||
*
|
*
|
||||||
* \param msg The message to be committed
|
* \param msg The message to be committed
|
||||||
@@ -113,7 +121,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Commits the offsets on the given topic/partitions synchronously
|
* \brief Commits the offsets on the given topic/partitions synchronously
|
||||||
*
|
*
|
||||||
* This will call Consumer::commit until either the offsets are successfully
|
* This will call Consumer::commit(topic_partitions) until either the offsets are successfully
|
||||||
* committed or the error callback returns false (if any is set).
|
* committed or the error callback returns false (if any is set).
|
||||||
*
|
*
|
||||||
* \param topic_partitions The topic/partition list to be committed
|
* \param topic_partitions The topic/partition list to be committed
|
||||||
@@ -127,26 +135,35 @@ public:
|
|||||||
*/
|
*/
|
||||||
Consumer& get_consumer();
|
Consumer& get_consumer();
|
||||||
private:
|
private:
|
||||||
// Return true to abort and false to continue committing
|
// If the ReturnType contains 'true', we abort committing. Otherwise we continue.
|
||||||
|
// The second member of the ReturnType contains the RdKafka error if any.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool do_commit(const T& object) {
|
ReturnType do_commit(const T* object) {
|
||||||
|
ReturnType rt;
|
||||||
try {
|
try {
|
||||||
consumer_.commit(object);
|
if (!object) {
|
||||||
// If the commit succeeds, we're done
|
consumer_.commit();
|
||||||
return true;
|
}
|
||||||
|
else {
|
||||||
|
consumer_.commit(*object);
|
||||||
|
}
|
||||||
|
// If the commit succeeds, we're done.
|
||||||
}
|
}
|
||||||
catch (const HandleException& ex) {
|
catch (const HandleException& ex) {
|
||||||
|
rt.error_ = ex.get_error();
|
||||||
// If there were actually no offsets to commit, return. Retrying won't solve
|
// If there were actually no offsets to commit, return. Retrying won't solve
|
||||||
// anything here
|
// anything here
|
||||||
if (ex.get_error() == RD_KAFKA_RESP_ERR__NO_OFFSET) {
|
if (rt.error_ != RD_KAFKA_RESP_ERR__NO_OFFSET) {
|
||||||
return true;
|
// If there's no callback or if returns true for this message, keep committing.
|
||||||
}
|
// Otherwise abort.
|
||||||
// If there's a callback and it returns false for this message, abort.
|
|
||||||
// Otherwise keep committing.
|
|
||||||
CallbackInvoker<ErrorCallback> callback("backoff committer", callback_, &consumer_);
|
CallbackInvoker<ErrorCallback> callback("backoff committer", callback_, &consumer_);
|
||||||
return callback && !callback(ex.get_error());
|
if (!callback || callback(rt.error_)) {
|
||||||
|
rt.abort_ = false; //continue retrying
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
Consumer& consumer_;
|
Consumer& consumer_;
|
||||||
ErrorCallback callback_;
|
ErrorCallback callback_;
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "../consumer.h"
|
#include "../consumer.h"
|
||||||
|
#include "../exceptions.h"
|
||||||
|
|
||||||
namespace cppkafka {
|
namespace cppkafka {
|
||||||
|
|
||||||
@@ -48,6 +49,14 @@ public:
|
|||||||
static const TimeUnit DEFAULT_MAXIMUM_BACKOFF;
|
static const TimeUnit DEFAULT_MAXIMUM_BACKOFF;
|
||||||
static const size_t DEFAULT_MAXIMUM_RETRIES;
|
static const size_t DEFAULT_MAXIMUM_RETRIES;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type which any functor must return.
|
||||||
|
*/
|
||||||
|
struct ReturnType {
|
||||||
|
bool abort_{true};
|
||||||
|
Error error_;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The backoff policy to use
|
* The backoff policy to use
|
||||||
*/
|
*/
|
||||||
@@ -119,11 +128,16 @@ public:
|
|||||||
void perform(const Functor& callback) {
|
void perform(const Functor& callback) {
|
||||||
TimeUnit backoff = initial_backoff_;
|
TimeUnit backoff = initial_backoff_;
|
||||||
size_t retries = maximum_retries_;
|
size_t retries = maximum_retries_;
|
||||||
|
ReturnType rt;
|
||||||
while (retries--) {
|
while (retries--) {
|
||||||
auto start = std::chrono::steady_clock::now();
|
auto start = std::chrono::steady_clock::now();
|
||||||
// If the callback returns true, we're done
|
// If the callback returns true, we're done
|
||||||
if (callback()) {
|
rt = callback();
|
||||||
return;
|
if (rt.abort_) {
|
||||||
|
if (rt.error_) {
|
||||||
|
break; //terminal error
|
||||||
|
}
|
||||||
|
return; //success
|
||||||
}
|
}
|
||||||
auto end = std::chrono::steady_clock::now();
|
auto end = std::chrono::steady_clock::now();
|
||||||
auto time_elapsed = end - start;
|
auto time_elapsed = end - start;
|
||||||
@@ -134,6 +148,8 @@ public:
|
|||||||
// Increase out backoff depending on the policy being used
|
// Increase out backoff depending on the policy being used
|
||||||
backoff = increase_backoff(backoff);
|
backoff = increase_backoff(backoff);
|
||||||
}
|
}
|
||||||
|
// No more retries left or we have a terminal error.
|
||||||
|
throw ConsumerException(rt.error_);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
TimeUnit increase_backoff(TimeUnit backoff);
|
TimeUnit increase_backoff(TimeUnit backoff);
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ using std::vector;
|
|||||||
using std::set;
|
using std::set;
|
||||||
using std::ostream;
|
using std::ostream;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::equal;
|
|
||||||
|
|
||||||
namespace cppkafka {
|
namespace cppkafka {
|
||||||
|
|
||||||
|
|||||||
@@ -43,15 +43,21 @@ void BackoffCommitter::set_error_callback(ErrorCallback callback) {
|
|||||||
callback_ = move(callback);
|
callback_ = move(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BackoffCommitter::commit() {
|
||||||
|
perform([&]()->ReturnType {
|
||||||
|
return do_commit<TopicPartitionList>(nullptr);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void BackoffCommitter::commit(const Message& msg) {
|
void BackoffCommitter::commit(const Message& msg) {
|
||||||
perform([&] {
|
perform([&]()->ReturnType {
|
||||||
return do_commit(msg);
|
return do_commit(&msg);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackoffCommitter::commit(const TopicPartitionList& topic_partitions) {
|
void BackoffCommitter::commit(const TopicPartitionList& topic_partitions) {
|
||||||
perform([&] {
|
perform([&]()->ReturnType {
|
||||||
return do_commit(topic_partitions);
|
return do_commit(&topic_partitions);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user