Current section
Files
Jump to
Current section
Files
c_src/erlkaf_config.cc
#include "erlkaf_config.h"
#include "nif_utils.h"
#include "erlkaf_nif.h"
#include "rdkafka.h"
#include "macros.h"
#include <functional>
#include <signal.h>
#include <string>
namespace {
template <typename T> struct set_config_fun
{
std::function<rd_kafka_conf_res_t (T *conf, const char *name, const char *value, char *errstr, size_t errstr_size)> set_value;
};
const set_config_fun<rd_kafka_topic_conf_t> kTopicConfFuns = {
rd_kafka_topic_conf_set
};
const set_config_fun<rd_kafka_conf_t> kKafkaConfFuns = {
rd_kafka_conf_set
};
template <typename T> ERL_NIF_TERM parse_config(ErlNifEnv* env, ERL_NIF_TERM list, T* conf, set_config_fun<T> fun)
{
if(!enif_is_list(env, list))
return make_bad_options(env, list);
char errstr[512];
ERL_NIF_TERM head;
const ERL_NIF_TERM *items;
int arity;
while(enif_get_list_cell(env, list, &head, &list))
{
if(!enif_get_tuple(env, head, &arity, &items) || arity != 2)
return make_bad_options(env, head);
std::string key;
std::string value;
if(!get_string(env, items[0], &key))
return make_bad_options(env, head);
if(!get_string(env, items[1], &value))
return make_bad_options(env, head);
if(fun.set_value(conf, key.c_str(), value.c_str(), errstr, sizeof(errstr)) != RD_KAFKA_CONF_OK)
return make_error(env, errstr);
}
return ATOMS.atomOk;
}
bool appy_kafka_default_config(rd_kafka_conf_t* config)
{
if(rd_kafka_conf_set(config, "enable.auto.commit", "true", NULL, 0) != RD_KAFKA_CONF_OK)
return false;
if(rd_kafka_conf_set(config, "enable.auto.offset.store", "false", NULL, 0) != RD_KAFKA_CONF_OK)
return false;
if(rd_kafka_conf_set(config, "enable.partition.eof", "false", NULL, 0) != RD_KAFKA_CONF_OK)
return false;
if(rd_kafka_conf_set(config, "allow.auto.create.topics", "true", NULL, 0) != RD_KAFKA_CONF_OK)
return false;
#ifdef SIGIO
// quick termination
char tmp[128];
snprintf(tmp, sizeof(tmp), "%i", SIGIO);
if(rd_kafka_conf_set(config, "internal.termination.signal", tmp, NULL, 0) != RD_KAFKA_CONF_OK)
return false;
#endif
return true;
}
bool appy_topic_default_config(rd_kafka_topic_conf_t* config)
{
if(rd_kafka_topic_conf_set(config, "message.timeout.ms", "0", NULL, 0) != RD_KAFKA_CONF_OK)
return false;
UNUSED(config);
return true;
}
} // namespace
ERL_NIF_TERM parse_topic_config(ErlNifEnv* env, ERL_NIF_TERM list, rd_kafka_topic_conf_t* conf)
{
if(!appy_topic_default_config(conf))
return make_error(env, "failed to apply default topic config");
return parse_config(env, list, conf, kTopicConfFuns);
}
ERL_NIF_TERM parse_kafka_config(ErlNifEnv* env, ERL_NIF_TERM list, rd_kafka_conf_t* conf)
{
if(!appy_kafka_default_config(conf))
return make_error(env, "failed to apply default kafka config");
return parse_config(env, list, conf, kKafkaConfFuns);
}