You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by er...@apache.org on 2018/02/08 13:21:25 UTC
celix git commit: etcd_get_directory retrieves the index from the
HTTP header instead of the last modified index in the content
Repository: celix
Updated Branches:
refs/heads/develop 490811d2c -> 7b3d1a8e5
etcd_get_directory retrieves the index from the HTTP header instead of the last modified index in the content
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/7b3d1a8e
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/7b3d1a8e
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/7b3d1a8e
Branch: refs/heads/develop
Commit: 7b3d1a8e5ddca7b4f72897c2be8ff26e55e50a5d
Parents: 490811d
Author: Erjan Altena <er...@gmail.com>
Authored: Thu Feb 8 14:20:54 2018 +0100
Committer: Erjan Altena <er...@gmail.com>
Committed: Thu Feb 8 14:20:54 2018 +0100
----------------------------------------------------------------------
etcdlib/src/etcd.c | 102 ++++++++++++++++++++++++++++++++++++------------
1 file changed, 78 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/7b3d1a8e/etcdlib/src/etcd.c
----------------------------------------------------------------------
diff --git a/etcdlib/src/etcd.c b/etcdlib/src/etcd.c
index cb5c0ff..861b07a 100644
--- a/etcdlib/src/etcd.c
+++ b/etcdlib/src/etcd.c
@@ -35,6 +35,8 @@
#define ETCD_JSON_MODIFIEDINDEX "modifiedIndex"
#define ETCD_JSON_INDEX "index"
+#define ETCD_HEADER_INDEX "X-Etcd-Index: "
+
#define MAX_OVERHEAD_LENGTH 64
#define DEFAULT_CURL_TIMEOUT 10
#define DEFAULT_CURL_CONECTTIMEOUT 10
@@ -48,14 +50,16 @@ static int etcd_port = 0;
struct MemoryStruct {
char *memory;
- size_t size;
+ char *header;
+ size_t memorySize;
+ size_t headerSize;
};
/**
* Static function declarations
*/
-static int performRequest(char* url, request_t request, void* callback, void* reqData, void* repData);
+static int performRequest(char* url, request_t request, void* reqData, void* repData);
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp);
/**
* External function definition
@@ -92,12 +96,14 @@ int etcd_get(const char* key, char** value, int* modifiedIndex) {
struct MemoryStruct reply;
reply.memory = malloc(1); /* will be grown as needed by the realloc above */
- reply.size = 0; /* no data at this point */
+ reply.memorySize = 0; /* no data at this point */
+ reply.header = NULL; /* will be grown as needed by the realloc above */
+ reply.headerSize = 0; /* no data at this point */
int retVal = -1;
char *url;
asprintf(&url, "http://%s:%d/v2/keys/%s", etcd_server, etcd_port, key);
- res = performRequest(url, GET, WriteMemoryCallback, NULL, (void*) &reply);
+ res = performRequest(url, GET, NULL, (void*) &reply);
free(url);
if (res == CURLE_OK) {
@@ -178,6 +184,17 @@ static int etcd_get_recursive_values(json_t* js_root, etcd_key_value_callback ca
return (*mod_index > 0 ? 0 : 1);
}
+static long long etcd_get_current_index(const char* headerData) {
+ long long index = -1;
+ char * indexStr = strstr(headerData, ETCD_HEADER_INDEX);
+ indexStr += strlen(ETCD_HEADER_INDEX);
+
+ if (sscanf(indexStr, "%lld\n",&index) == 1) {
+ } else {
+ index = -1;
+ }
+ return index;
+}
/**
* etcd_get_directory
*/
@@ -190,14 +207,16 @@ int etcd_get_directory(const char* directory, etcd_key_value_callback callback,
struct MemoryStruct reply;
reply.memory = malloc(1); /* will be grown as needed by the realloc above */
- reply.size = 0; /* no data at this point */
+ reply.memorySize = 0; /* no data at this point */
+ reply.header = malloc(1); /* will be grown as needed by the realloc above */
+ reply.headerSize = 0; /* no data at this point */
int retVal = 0;
char *url;
asprintf(&url, "http://%s:%d/v2/keys/%s?recursive=true", etcd_server, etcd_port, directory);
- res = performRequest(url, GET, WriteMemoryCallback, NULL, (void*) &reply);
+ res = performRequest(url, GET, NULL, (void*) &reply);
free(url);
if (res == CURLE_OK) {
js_root = json_loads(reply.memory, 0, &error);
@@ -210,6 +229,10 @@ int etcd_get_directory(const char* directory, etcd_key_value_callback callback,
if (js_rootnode != NULL) {
*modifiedIndex = 0;
retVal = etcd_get_recursive_values(js_rootnode, callback, arg, (json_int_t*)modifiedIndex);
+ long long indexFromHeader = etcd_get_current_index(reply.header);
+ if (indexFromHeader > *modifiedIndex) {
+ *modifiedIndex = indexFromHeader;
+ }
} else {
// Error occured, retrieve the index of ETCD from the error code
js_rootnode = json_object_get(js_root, ETCD_JSON_INDEX);
@@ -228,9 +251,8 @@ int etcd_get_directory(const char* directory, etcd_key_value_callback callback,
}
}
- if (reply.memory) {
- free(reply.memory);
- }
+ free(reply.memory);
+ free(reply.header);
return retVal;
}
@@ -257,7 +279,9 @@ int etcd_set(const char* key, const char* value, int ttl, bool prevExist) {
}
reply.memory = calloc(1, 1); /* will be grown as needed by the realloc above */
- reply.size = 0; /* no data at this point */
+ reply.memorySize = 0; /* no data at this point */
+ reply.header = NULL; /* will be grown as needed by the realloc above */
+ reply.headerSize = 0; /* no data at this point */
asprintf(&url, "http://%s:%d/v2/keys/%s", etcd_server, etcd_port, key);
@@ -270,7 +294,7 @@ int etcd_set(const char* key, const char* value, int ttl, bool prevExist) {
requestPtr += snprintf(requestPtr, req_len-(requestPtr-request), ";prevExist=true");
}
- res = performRequest(url, PUT, WriteMemoryCallback, request, (void*) &reply);
+ res = performRequest(url, PUT, request, (void*) &reply);
if(url) {
free(url);
}
@@ -346,13 +370,18 @@ int etcd_watch(const char* key, long long index, char** action, char** prevValue
struct MemoryStruct reply;
reply.memory = malloc(1); /* will be grown as needed by the realloc above */
- reply.size = 0; /* no data at this point */
+ reply.memorySize = 0; /* no data at this point */
+ reply.header = NULL; /* will be grown as needed by the realloc above */
+ reply.headerSize = 0; /* no data at this point */
+
+ reply.header = malloc(1); /* will be grown as needed by the realloc above */
+ reply.headerSize = 0; /* no data at this point */
if (index != 0)
asprintf(&url, "http://%s:%d/v2/keys/%s?wait=true&recursive=true&waitIndex=%lld", etcd_server, etcd_port, key, index);
else
asprintf(&url, "http://%s:%d/v2/keys/%s?wait=true&recursive=true", etcd_server, etcd_port, key);
- res = performRequest(url, GET, WriteMemoryCallback, NULL, (void*) &reply);
+ res = performRequest(url, GET, NULL, (void*) &reply);
if(url)
free(url);
if (res == CURLE_OK) {
@@ -422,10 +451,12 @@ int etcd_del(const char* key) {
struct MemoryStruct reply;
reply.memory = malloc(1); /* will be grown as needed by the realloc above */
- reply.size = 0; /* no data at this point */
+ reply.memorySize = 0; /* no data at this point */
+ reply.header = NULL; /* will be grown as needed by the realloc above */
+ reply.headerSize = 0; /* no data at this point */
asprintf(&url, "http://%s:%d/v2/keys/%s?recursive=true", etcd_server, etcd_port, key);
- res = performRequest(url, DELETE, WriteMemoryCallback, NULL, (void*) &reply);
+ res = performRequest(url, DELETE, NULL, (void*) &reply);
free(url);
if (res == CURLE_OK) {
@@ -443,9 +474,8 @@ int etcd_del(const char* key) {
}
}
- if (reply.memory) {
- free(reply.memory);
- }
+ free(reply.memory);
+ free(reply.header);
return retVal;
}
@@ -455,21 +485,41 @@ static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, voi
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *) userp;
- mem->memory = realloc(mem->memory, mem->size + realsize + 1);
+ mem->memory = realloc(mem->memory, mem->memorySize + realsize + 1);
if (mem->memory == NULL) {
/* out of memory! */
fprintf(stderr, "[ETCDLIB] Error: not enough memory (realloc returned NULL)\n");
return 0;
}
- memcpy(&(mem->memory[mem->size]), contents, realsize);
- mem->size += realsize;
- mem->memory[mem->size] = 0;
+ memcpy(&(mem->memory[mem->memorySize]), contents, realsize);
+ mem->memorySize += realsize;
+ mem->memory[mem->memorySize] = 0;
return realsize;
}
-static int performRequest(char* url, request_t request, void* callback, void* reqData, void* repData) {
+static size_t WriteHeaderCallback(void *contents, size_t size, size_t nmemb, void *userp) {
+ size_t realsize = size * nmemb;
+ struct MemoryStruct *mem = (struct MemoryStruct *) userp;
+
+ mem->header = realloc(mem->header, mem->headerSize + realsize + 1);
+ if (mem->header == NULL) {
+ /* out of memory! */
+ fprintf(stderr, "[ETCDLIB] Error: not enough header-memory (realloc returned NULL)\n");
+ return 0;
+ }
+
+ memcpy(&(mem->header[mem->headerSize]), contents, realsize);
+ mem->headerSize += realsize;
+ mem->header[mem->headerSize] = 0;
+
+ return realsize;
+}
+
+
+
+static int performRequest(char* url, request_t request, void* reqData, void* repData) {
CURL *curl = NULL;
CURLcode res = 0;
curl = curl_easy_init();
@@ -478,8 +528,12 @@ static int performRequest(char* url, request_t request, void* callback, void* re
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, DEFAULT_CURL_CONECTTIMEOUT);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, repData);
+ if (((struct MemoryStruct*)repData)->header) {
+ curl_easy_setopt(curl, CURLOPT_HEADERDATA, repData);
+ curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, WriteHeaderCallback);
+ }
if (request == PUT) {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");