This document provides comprehensive API reference for the librale distributed consensus and key-value store library. All public APIs are thread-safe and designed for production use.
#include <librale.h>#include <public_api.h>typedef struct Node {
int id; /* Unique node identifier */
char name[MAX_NODE_NAME]; /* Human-readable node name */
char ip[MAX_IP_LENGTH]; /* IP address */
int rale_port; /* RALE consensus port */
int dstore_port; /* DStore service port */
int state; /* Current node state */
int priority; /* Election priority */
int term; /* Current term number */
int last_log_index; /* Last log index */
int last_log_term; /* Last log term */
} Node;typedef struct rale_context_t {
pthread_mutex_t mutex; /* Thread synchronization */
pthread_cond_t cond; /* Condition variable */
int initialized; /* Initialization flag */
} rale_context_t;typedef enum {
LOG_ERROR = 0, /* Error conditions */
LOG_INFO = 1, /* Informational messages */
LOG_WARNING = 2, /* Warning conditions */
LOG_DEBUG = 3 /* Debug messages */
} LogLevel;#define LIBRALE_SUCCESS 0 /* Operation successful */
#define LIBRALE_ERROR -1 /* General error */
#define LIBRALE_ERROR_MEMORY -2 /* Memory allocation error */
#define LIBRALE_ERROR_NETWORK -3 /* Network error */
#define LIBRALE_ERROR_TIMEOUT -4 /* Timeout error */
#define LIBRALE_ERROR_INVALID -5 /* Invalid parameter */Creates a new RALE context for thread-safe operations.
rale_context_t *librale_context_create(void);Returns:
- Pointer to initialized context on success
NULLon memory allocation failure
Example:
rale_context_t *ctx = librale_context_create();
if (ctx == NULL) {
fprintf(stderr, "Failed to create RALE context\n");
return -1;
}Destroys a RALE context and releases resources.
void librale_context_destroy(rale_context_t *ctx);Parameters:
ctx: Context to destroy (can beNULL)
Example:
librale_context_destroy(ctx);
ctx = NULL;Initializes the cluster subsystem.
int librale_cluster_init(void);Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Example:
if (librale_cluster_init() != LIBRALE_SUCCESS) {
fprintf(stderr, "Failed to initialize cluster\n");
return -1;
}Adds a node to the cluster configuration.
int librale_cluster_add_node(int node_id, const char *name, const char *ip,
int rale_port, int dstore_port);Parameters:
node_id: Unique node identifier (0-9999)name: Human-readable node nameip: IP address stringrale_port: Port for RALE consensus protocoldstore_port: Port for DStore operations
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Example:
int result = librale_cluster_add_node(1, "node1", "10.0.0.1", 7400, 7401);
if (result != LIBRALE_SUCCESS) {
fprintf(stderr, "Failed to add node to cluster\n");
return -1;
}Removes a node from the cluster configuration.
int librale_cluster_remove_node(int node_id);Parameters:
node_id: Node identifier to remove
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Retrieves current cluster node list.
int librale_cluster_get_nodes(Node *nodes, int *count, int max_nodes);Parameters:
nodes: Array to store node informationcount: Pointer to store actual node countmax_nodes: Maximum nodes array can hold
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Example:
Node nodes[10];
int count;
int result = librale_cluster_get_nodes(nodes, &count, 10);
if (result == LIBRALE_SUCCESS) {
printf("Cluster has %d nodes\n", count);
for (int i = 0; i < count; i++) {
printf("Node %d: %s (%s:%d)\n",
nodes[i].id, nodes[i].name, nodes[i].ip, nodes[i].rale_port);
}
}Initializes the RALE consensus subsystem.
int librale_rale_init(int node_id, const char *data_dir);Parameters:
node_id: This node's identifierdata_dir: Directory for persistent state
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Starts the RALE consensus protocol.
int librale_rale_start(void);Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Stops the RALE consensus protocol.
int librale_rale_stop(void);Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Checks if this node is the current leader.
int librale_rale_is_leader(void);Returns:
1if this node is leader0if this node is not leaderLIBRALE_ERRORon error
Example:
int is_leader = librale_rale_is_leader();
if (is_leader == 1) {
printf("This node is the leader\n");
} else if (is_leader == 0) {
printf("This node is a follower\n");
} else {
fprintf(stderr, "Error checking leadership status\n");
}Gets the current cluster leader information.
int librale_rale_get_leader(int *leader_id);Parameters:
leader_id: Pointer to store leader node ID
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Initializes the distributed store subsystem.
int librale_dstore_init(const char *data_dir);Parameters:
data_dir: Directory for data storage
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Stores a key-value pair in the distributed store.
int librale_dstore_put(const char *key, const void *value, size_t value_len);Parameters:
key: Key string (null-terminated)value: Value datavalue_len: Length of value data
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Example:
const char *key = "user:123:name";
const char *value = "John Doe";
int result = librale_dstore_put(key, value, strlen(value));
if (result != LIBRALE_SUCCESS) {
fprintf(stderr, "Failed to store key-value pair\n");
}Retrieves a value by key from the distributed store.
int librale_dstore_get(const char *key, void *value, size_t *value_len);Parameters:
key: Key string to lookupvalue: Buffer to store retrieved valuevalue_len: Pointer to buffer size (input) and actual size (output)
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Example:
char buffer[1024];
size_t len = sizeof(buffer);
int result = librale_dstore_get("user:123:name", buffer, &len);
if (result == LIBRALE_SUCCESS) {
buffer[len] = '\0'; /* Null-terminate if string */
printf("Retrieved value: %s\n", buffer);
} else {
fprintf(stderr, "Key not found or error occurred\n");
}Deletes a key from the distributed store.
int librale_dstore_delete(const char *key);Parameters:
key: Key string to delete
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Lists keys matching a prefix.
int librale_dstore_list(const char *prefix, char **keys, int *count, int max_keys);Parameters:
prefix: Key prefix to matchkeys: Array of string pointers to store keyscount: Pointer to store actual key countmax_keys: Maximum keys array can hold
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Initializes network subsystem.
int librale_network_init(void);Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Starts network services (TCP/UDP servers).
int librale_network_start(int rale_port, int dstore_port);Parameters:
rale_port: Port for RALE consensus protocoldstore_port: Port for DStore operations
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Stops network services.
int librale_network_stop(void);Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Loads configuration from file.
int librale_config_load(const char *config_file);Parameters:
config_file: Path to configuration file
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Gets a configuration value.
int librale_config_get(const char *key, char *value, size_t value_len);Parameters:
key: Configuration keyvalue: Buffer to store valuevalue_len: Buffer size
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Sets a configuration value.
int librale_config_set(const char *key, const char *value);Parameters:
key: Configuration keyvalue: Configuration value
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
typedef int (*librale_log_callback_t)(librale_log_level level,
const char *prefix,
const char *message,
const char *detail,
const char *hint);Sets a custom log callback function.
int librale_log_set_callback(librale_log_callback_t callback);Parameters:
callback: Log callback function (orNULLto disable)
Returns:
LIBRALE_SUCCESSon success
Sets the minimum log level.
int librale_log_set_level(librale_log_level level);Parameters:
level: Minimum log level to output
Returns:
LIBRALE_SUCCESSon success
Outputs a log message.
void elog(librale_log_level level, const char *prefix, const char *format, ...);Parameters:
level: Log levelprefix: Module prefix (e.g., "RALE", "DSTORE")format: Printf-style format string...: Format arguments
Example:
elog(LOG_INFO, "RALE", "Node %d elected as leader", node_id);
elog(LOG_ERROR, "DSTORE", "Failed to open database: %s", strerror(errno));Reports an error with detail and hint.
void ereport(librale_log_level level, const char *prefix,
const char *message, const char *detail, const char *hint);Parameters:
level: Log levelprefix: Module prefixmessage: Main error messagedetail: Detailed error informationhint: Suggestion for resolution
Example:
ereport(LOG_ERROR, "RALE",
"Failed to connect to peer node",
"Connection timeout after 30 seconds",
"Check network connectivity and firewall settings");Gets current system status.
int librale_status_get(char *status_json, size_t buffer_len);Parameters:
status_json: Buffer to store JSON statusbuffer_len: Buffer size
Returns:
LIBRALE_SUCCESSon successLIBRALE_ERRORon failure
Example:
char status[4096];
int result = librale_status_get(status, sizeof(status));
if (result == LIBRALE_SUCCESS) {
printf("System Status: %s\n", status);
}Performs a health check.
int librale_health_check(void);Returns:
LIBRALE_SUCCESSif healthyLIBRALE_ERRORif unhealthy
Cleans up all librale resources.
void librale_cleanup(void);Note: Call this before program exit to ensure clean shutdown.
Example:
/* At program exit */
librale_cleanup();Always check return values from librale functions:
int result = librale_cluster_init();
if (result != LIBRALE_SUCCESS) {
elog(LOG_ERROR, "APP", "Failed to initialize cluster");
return -1;
}Use proper resource management patterns:
rale_context_t *ctx = librale_context_create();
if (ctx == NULL) {
return -1;
}
/* Use context... */
librale_context_destroy(ctx);
ctx = NULL;All public APIs are thread-safe, but contexts should not be shared:
/* Create separate contexts for different threads */
rale_context_t *ctx1 = librale_context_create(); /* Thread 1 */
rale_context_t *ctx2 = librale_context_create(); /* Thread 2 */#include <librale.h>
int main() {
/* Initialize */
if (librale_cluster_init() != LIBRALE_SUCCESS) {
return -1;
}
if (librale_rale_init(1, "/var/lib/rale") != LIBRALE_SUCCESS) {
return -1;
}
if (librale_dstore_init("/var/lib/rale/data") != LIBRALE_SUCCESS) {
return -1;
}
/* Start services */
librale_rale_start();
librale_network_start(7400, 7401);
/* Store data */
librale_dstore_put("key1", "value1", 6);
/* Retrieve data */
char buffer[1024];
size_t len = sizeof(buffer);
if (librale_dstore_get("key1", buffer, &len) == LIBRALE_SUCCESS) {
printf("Retrieved: %.*s\n", (int)len, buffer);
}
/* Cleanup */
librale_cleanup();
return 0;
}#include <librale.h>
void monitor_leadership() {
int current_leader = -1;
while (1) {
int leader_id;
if (librale_rale_get_leader(&leader_id) == LIBRALE_SUCCESS) {
if (leader_id != current_leader) {
printf("Leadership changed: Node %d is now leader\n", leader_id);
current_leader = leader_id;
}
}
sleep(1);
}
}This API reference provides comprehensive coverage of all public librale APIs with examples and best practices for integration into distributed applications.