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");