You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by bp...@apache.org on 2014/09/25 06:56:29 UTC

svn commit: r1627454 - in /celix/trunk/remote_services/discovery_etcd/private: include/etcd.h src/etcd.c src/etcd_watcher.c

Author: bpetri
Date: Thu Sep 25 04:56:28 2014
New Revision: 1627454

URL: http://svn.apache.org/r1627454
Log:

CELIX-152: add ttl support for etcd


Modified:
    celix/trunk/remote_services/discovery_etcd/private/include/etcd.h
    celix/trunk/remote_services/discovery_etcd/private/src/etcd.c
    celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c

Modified: celix/trunk/remote_services/discovery_etcd/private/include/etcd.h
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_etcd/private/include/etcd.h?rev=1627454&r1=1627453&r2=1627454&view=diff
==============================================================================
--- celix/trunk/remote_services/discovery_etcd/private/include/etcd.h (original)
+++ celix/trunk/remote_services/discovery_etcd/private/include/etcd.h Thu Sep 25 04:56:28 2014
@@ -21,7 +21,7 @@
 bool etcd_init(char* server, int port);
 bool etcd_get(char* key, char* value, char*action, int* modifiedIndex);
 bool etcd_getNodes(char* directory, char** nodeNames, int* size);
-bool etcd_set(char* key, char* value);
+bool etcd_set(char* key, char* value, int ttl);
 bool etcd_del(char* key);
 bool etcd_watch(char* key, int index, char* action, char* prevValue, char* value);
 

Modified: celix/trunk/remote_services/discovery_etcd/private/src/etcd.c
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_etcd/private/src/etcd.c?rev=1627454&r1=1627453&r2=1627454&view=diff
==============================================================================
--- celix/trunk/remote_services/discovery_etcd/private/src/etcd.c (original)
+++ celix/trunk/remote_services/discovery_etcd/private/src/etcd.c Thu Sep 25 04:56:28 2014
@@ -5,16 +5,17 @@
 #include <curl/curl.h>
 #include <jansson.h>
 
-
-
 #include "etcd.h"
 
+#define DEFAULT_CURL_TIMEOUT          10
+#define DEFAULT_CURL_CONECTTIMEOUT    10
+
 typedef enum {
 	GET, PUT, DELETE
 } request_t;
 
 static char* etcd_server = NULL;
-static int etcd_port = NULL;
+static int etcd_port = 0;
 
 struct MemoryStruct {
 	char *memory;
@@ -44,8 +45,8 @@ static int performRequest(char* url, req
 	CURLcode res = 0;
 
 	curl = curl_easy_init();
-	curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
-	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
+	curl_easy_setopt(curl, CURLOPT_TIMEOUT, DEFAULT_CURL_TIMEOUT);
+	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);
@@ -175,7 +176,7 @@ bool etcd_getNodes(char* directory, char
 }
 
 //set
-bool etcd_set(char* key, char* value) {
+bool etcd_set(char* key, char* value, int ttl) {
 	json_error_t error;
 	json_t* js_root;
 	json_t* js_node;
@@ -190,7 +191,11 @@ bool etcd_set(char* key, char* value) {
 	reply.size = 0; /* no data at this point */
 
 	snprintf(url, MAX_URL_LENGTH, "http://%s:%d/v2/keys/%s", etcd_server, etcd_port, key);
-	snprintf(request, MAX_CONTENT_LENGTH, "value=%s", value);
+
+	if (ttl > 0)
+	    snprintf(request, MAX_CONTENT_LENGTH, "value=%s", value);
+	else
+	    snprintf(request, MAX_CONTENT_LENGTH, "value=%s;ttl=%d", value, ttl);
 
 	res = performRequest(url, PUT, WriteMemoryCallback, request, (void*) &reply);
 	if (res == CURLE_OPERATION_TIMEDOUT) {

Modified: celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c?rev=1627454&r1=1627453&r2=1627454&view=diff
==============================================================================
--- celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c (original)
+++ celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c Thu Sep 25 04:56:28 2014
@@ -53,6 +53,10 @@ struct etcd_watcher {
 #define CFG_ETCD_SERVER_PORT	"DISCOVERY_ETCD_SERVER_PORT"
 #define DEFAULT_ETCD_SERVER_PORT 4001
 
+// be careful - this should be higher than the curl timeout
+#define CFG_ETCD_TTL   "DISCOVERY_ETCD_TTL"
+#define DEFAULT_ETCD_TTL 30
+
 
 // note that the rootNode shouldn't have a leading slash
 static celix_status_t etcdWatcher_getRootPath(char* rootNode) {
@@ -132,6 +136,49 @@ static celix_status_t etcdWatcher_addAlr
 	return status;
 }
 
+
+static celix_status_t etcdWatcher_addOwnFramework(bundle_context_pt context)
+{
+    celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+    char localNodePath[MAX_LOCALNODE_LENGTH];
+    char* endpoints = NULL;
+    char* ttlStr = NULL;
+    int ttl;
+
+    // register own framework
+    if ((status = etcdWatcher_getLocalNodePath(context, &localNodePath[0])) != CELIX_SUCCESS) {
+        return status;
+    }
+
+    if ((bundleContext_getProperty(context, DISCOVERY_POLL_ENDPOINTS, &endpoints) != CELIX_SUCCESS) || !endpoints) {
+        endpoints = DEFAULT_POLL_ENDPOINTS;
+    }
+
+    if ((bundleContext_getProperty(context, CFG_ETCD_TTL, &ttlStr) != CELIX_SUCCESS) || !ttlStr) {
+        ttl = DEFAULT_ETCD_TTL;
+    }
+    else
+    {
+        char* endptr = ttlStr;
+        errno = 0;
+        ttl =  strtol(ttlStr, &endptr, 10);
+        if (*endptr || errno != 0) {
+            ttl = DEFAULT_ETCD_TTL;
+        }
+    }
+
+    if (etcd_set(localNodePath, endpoints, ttl) == false)
+    {
+        fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Cannot register local discovery");
+    }
+    else
+    {
+        status = CELIX_SUCCESS;
+    }
+
+    return status;
+}
+
 /*
  * performs (blocking) etcd_watch calls to check for
  * changing discovery endpoint information within etcd.
@@ -161,6 +208,8 @@ static void* etcdWatcher_run(void* data)
 				fw_log(logger, OSGI_FRAMEWORK_LOG_INFO, "Unexpected action: %s", action);
 			}
 		}
+		// update own framework uuid in any case;
+	    etcdWatcher_addOwnFramework(watcher->context);
 	}
 
 	return NULL;
@@ -174,11 +223,10 @@ celix_status_t etcdWatcher_create(endpoi
 		etcd_watcher_pt *watcher)
 {
 	celix_status_t status = CELIX_SUCCESS;
-	char localNodePath[MAX_LOCALNODE_LENGTH];
+
 	char* etcd_server = NULL;
 	char* etcd_port_string = NULL;
-	int etcd_port = NULL;
-	char* endpoints = NULL;
+	int etcd_port = 0;
 
 	if (poller == NULL) {
 		return CELIX_BUNDLE_EXCEPTION;
@@ -211,9 +259,6 @@ celix_status_t etcdWatcher_create(endpoi
 		}
 	}
 
-	if ((bundleContext_getProperty(context, DISCOVERY_POLL_ENDPOINTS, &endpoints) != CELIX_SUCCESS) || !endpoints) {
-		endpoints = DEFAULT_POLL_ENDPOINTS;
-	}
 
 
 	if (etcd_init(etcd_server, etcd_port) == false)
@@ -221,17 +266,7 @@ celix_status_t etcdWatcher_create(endpoi
 		return CELIX_BUNDLE_EXCEPTION;
 	}
 
-	// register own framework
-	if ((status = etcdWatcher_getLocalNodePath(context, &localNodePath[0])) != CELIX_SUCCESS) {
-		return status;
-	}
-
-	if (etcd_set(localNodePath, endpoints) == false)
-	{
-		fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Cannot register local discovery");
-	}
-
-
+	etcdWatcher_addOwnFramework(context);
 
 	if ((status = celixThreadMutex_create(&(*watcher)->watcherLock, NULL)) != CELIX_SUCCESS) {
 		return status;



RE: svn commit: r1627454 - in /celix/trunk/remote_services/discovery_etcd/private: include/etcd.h src/etcd.c src/etcd_watcher.c

Posted by Isaac Rose <Is...@myfuelmaster.com>.
What does ttl stand for? Is it Time To Live?

-----Original Message-----
From: Bjoern Petri [mailto:bjoern.petri@sundevil.de] 
Sent: Tuesday, October 07, 2014 1:05 PM
To: dev@celix.apache.org
Subject: Re: svn commit: r1627454 - in /celix/trunk/remote_services/discovery_etcd/private: include/etcd.h src/etcd.c src/etcd_watcher.c


Hi Alexander,

the ttl specifies the specified time to live for the key in seconds. The discovery_etcd announces itself with a ttl of 30 seconds. If the etcd-watch of the amdatu discovery etcd-implementation (not the
endpoint_discovery_poller) takes more time than this, the described behavior occurs. Because the etcd-watch is nothing else than a long poll, the timeout values has to be set accordingly. The celix discovery-etcd implementation currently uses 10 seconds for that.

Regards,
   Bjoern


On 2014-10-07 18:26, Alexander Broekhuis wrote:
> Hi Bjoern,
> 
> I've updated to trunk, and now when I try to run a Celix -> Amdatu 
> example using Etcd, it doesn't work as expected.
> I haven't investigated this deeply, but when I disable the TTL code 
> (revert the changes from this (and the fix) commit, it works again. So 
> somewhere in this part something is going on.
> 
> What happens is that the service is picked up by Amdatu, is added, but 
> after some time is removed again. How is the TTL supposed to work? Is 
> this a consequence of the Amdatu poller not polling quick enough wrt 
> TTL set in Celix?
> 
> Thanks,
> 
> 2014-09-25 6:56 GMT+02:00 <bp...@apache.org>:
> 
>> Author: bpetri
>> Date: Thu Sep 25 04:56:28 2014
>> New Revision: 1627454
>> 
>> URL: http://svn.apache.org/r1627454
>> Log:
>> 
>> CELIX-152: add ttl support for etcd
>> 
>> 
>> Modified:
>>     celix/trunk/remote_services/discovery_etcd/private/include/etcd.h
>>     celix/trunk/remote_services/discovery_etcd/private/src/etcd.c
>>     
>> celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c
>> 
>> Modified: 
>> celix/trunk/remote_services/discovery_etcd/private/include/etcd.h
>> URL:
>> http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_et
>> cd/private/include/etcd.h?rev=1627454&r1=1627453&r2=1627454&view=diff
>> 
>> =====================================================================
>> =========
>> --- celix/trunk/remote_services/discovery_etcd/private/include/etcd.h
>> (original)
>> +++ celix/trunk/remote_services/discovery_etcd/private/include/etcd.h
>> Thu
>> Sep 25 04:56:28 2014
>> @@ -21,7 +21,7 @@
>>  bool etcd_init(char* server, int port);  bool etcd_get(char* key, 
>> char* value, char*action, int* modifiedIndex);  bool 
>> etcd_getNodes(char* directory, char** nodeNames, int* size); -bool 
>> etcd_set(char* key, char* value);
>> +bool etcd_set(char* key, char* value, int ttl);
>>  bool etcd_del(char* key);
>>  bool etcd_watch(char* key, int index, char* action, char* prevValue,
>> char* value);
>> 
>> 
>> Modified: 
>> celix/trunk/remote_services/discovery_etcd/private/src/etcd.c
>> URL:
>> http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_et
>> cd/private/src/etcd.c?rev=1627454&r1=1627453&r2=1627454&view=diff
>> 
>> =====================================================================
>> =========
>> --- celix/trunk/remote_services/discovery_etcd/private/src/etcd.c
>> (original)
>> +++ celix/trunk/remote_services/discovery_etcd/private/src/etcd.c Thu
>> Sep
>> 25 04:56:28 2014
>> @@ -5,16 +5,17 @@
>>  #include <curl/curl.h>
>>  #include <jansson.h>
>> 
>> -
>> -
>>  #include "etcd.h"
>> 
>> +#define DEFAULT_CURL_TIMEOUT          10
>> +#define DEFAULT_CURL_CONECTTIMEOUT    10
>> +
>>  typedef enum {
>>         GET, PUT, DELETE
>>  } request_t;
>> 
>>  static char* etcd_server = NULL;
>> -static int etcd_port = NULL;
>> +static int etcd_port = 0;
>> 
>>  struct MemoryStruct {
>>         char *memory;
>> @@ -44,8 +45,8 @@ static int performRequest(char* url, req
>>         CURLcode res = 0;
>> 
>>         curl = curl_easy_init();
>> -       curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
>> -       curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
>> +       curl_easy_setopt(curl, CURLOPT_TIMEOUT, DEFAULT_CURL_TIMEOUT);
>> +       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); @@ 
>> -175,7 +176,7 @@ bool etcd_getNodes(char* directory, char  }
>> 
>>  //set
>> -bool etcd_set(char* key, char* value) {
>> +bool etcd_set(char* key, char* value, int ttl) {
>>         json_error_t error;
>>         json_t* js_root;
>>         json_t* js_node;
>> @@ -190,7 +191,11 @@ bool etcd_set(char* key, char* value) {
>>         reply.size = 0; /* no data at this point */
>> 
>>         snprintf(url, MAX_URL_LENGTH, "http://%s:%d/v2/keys/%s", 
>> etcd_server, etcd_port, key);
>> -       snprintf(request, MAX_CONTENT_LENGTH, "value=%s", value);
>> +
>> +       if (ttl > 0)
>> +           snprintf(request, MAX_CONTENT_LENGTH, "value=%s", value);
>> +       else
>> +           snprintf(request, MAX_CONTENT_LENGTH, "value=%s;ttl=%d",
>> value, ttl);
>> 
>>         res = performRequest(url, PUT, WriteMemoryCallback, request,
>> (void*) &reply);
>>         if (res == CURLE_OPERATION_TIMEDOUT) {
>> 
>> Modified:
>> celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c
>> URL:
>> http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_et
>> cd/private/src/etcd_watcher.c?rev=1627454&r1=1627453&r2=1627454&view=
>> diff
>> 
>> =====================================================================
>> =========
>> ---
>> celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c
>> (original)
>> +++ 
>> celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c
>> Thu Sep 25 04:56:28 2014
>> @@ -53,6 +53,10 @@ struct etcd_watcher {
>>  #define CFG_ETCD_SERVER_PORT   "DISCOVERY_ETCD_SERVER_PORT"
>>  #define DEFAULT_ETCD_SERVER_PORT 4001
>> 
>> +// be careful - this should be higher than the curl timeout
>> +#define CFG_ETCD_TTL   "DISCOVERY_ETCD_TTL"
>> +#define DEFAULT_ETCD_TTL 30
>> +
>> 
>>  // note that the rootNode shouldn't have a leading slash  static 
>> celix_status_t etcdWatcher_getRootPath(char* rootNode) { @@ -132,6 
>> +136,49 @@ static celix_status_t etcdWatcher_addAlr
>>         return status;
>>  }
>> 
>> +
>> +static celix_status_t etcdWatcher_addOwnFramework(bundle_context_pt
>> context)
>> +{
>> +    celix_status_t status = CELIX_BUNDLE_EXCEPTION;
>> +    char localNodePath[MAX_LOCALNODE_LENGTH];
>> +    char* endpoints = NULL;
>> +    char* ttlStr = NULL;
>> +    int ttl;
>> +
>> +    // register own framework
>> +    if ((status = etcdWatcher_getLocalNodePath(context,
>> &localNodePath[0])) != CELIX_SUCCESS) {
>> +        return status;
>> +    }
>> +
>> +    if ((bundleContext_getProperty(context, 
>> + DISCOVERY_POLL_ENDPOINTS,
>> &endpoints) != CELIX_SUCCESS) || !endpoints) {
>> +        endpoints = DEFAULT_POLL_ENDPOINTS;
>> +    }
>> +
>> +    if ((bundleContext_getProperty(context, CFG_ETCD_TTL, &ttlStr) 
>> + !=
>> CELIX_SUCCESS) || !ttlStr) {
>> +        ttl = DEFAULT_ETCD_TTL;
>> +    }
>> +    else
>> +    {
>> +        char* endptr = ttlStr;
>> +        errno = 0;
>> +        ttl =  strtol(ttlStr, &endptr, 10);
>> +        if (*endptr || errno != 0) {
>> +            ttl = DEFAULT_ETCD_TTL;
>> +        }
>> +    }
>> +
>> +    if (etcd_set(localNodePath, endpoints, ttl) == false)
>> +    {
>> +        fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Cannot register
>> local
>> discovery");
>> +    }
>> +    else
>> +    {
>> +        status = CELIX_SUCCESS;
>> +    }
>> +
>> +    return status;
>> +}
>> +
>>  /*
>>   * performs (blocking) etcd_watch calls to check for
>>   * changing discovery endpoint information within etcd.
>> @@ -161,6 +208,8 @@ static void* etcdWatcher_run(void* data)
>>                                 fw_log(logger, 
>> OSGI_FRAMEWORK_LOG_INFO, "Unexpected action: %s", action);
>>                         }
>>                 }
>> +               // update own framework uuid in any case;
>> +           etcdWatcher_addOwnFramework(watcher->context);
>>         }
>> 
>>         return NULL;
>> @@ -174,11 +223,10 @@ celix_status_t etcdWatcher_create(endpoi
>>                 etcd_watcher_pt *watcher)  {
>>         celix_status_t status = CELIX_SUCCESS;
>> -       char localNodePath[MAX_LOCALNODE_LENGTH];
>> +
>>         char* etcd_server = NULL;
>>         char* etcd_port_string = NULL;
>> -       int etcd_port = NULL;
>> -       char* endpoints = NULL;
>> +       int etcd_port = 0;
>> 
>>         if (poller == NULL) {
>>                 return CELIX_BUNDLE_EXCEPTION; @@ -211,9 +259,6 @@ 
>> celix_status_t etcdWatcher_create(endpoi
>>                 }
>>         }
>> 
>> -       if ((bundleContext_getProperty(context, 
>> DISCOVERY_POLL_ENDPOINTS,
>> &endpoints) != CELIX_SUCCESS) || !endpoints) {
>> -               endpoints = DEFAULT_POLL_ENDPOINTS;
>> -       }
>> 
>> 
>>         if (etcd_init(etcd_server, etcd_port) == false) @@ -221,17 
>> +266,7 @@ celix_status_t etcdWatcher_create(endpoi
>>                 return CELIX_BUNDLE_EXCEPTION;
>>         }
>> 
>> -       // register own framework
>> -       if ((status = etcdWatcher_getLocalNodePath(context,
>> &localNodePath[0])) != CELIX_SUCCESS) {
>> -               return status;
>> -       }
>> -
>> -       if (etcd_set(localNodePath, endpoints) == false)
>> -       {
>> -               fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Cannot
>> register local discovery");
>> -       }
>> -
>> -
>> +       etcdWatcher_addOwnFramework(context);
>> 
>>         if ((status =
>> celixThreadMutex_create(&(*watcher)->watcherLock,
>> NULL)) != CELIX_SUCCESS) {
>>                 return status;
>> 
>> 
>> 

Re: svn commit: r1627454 - in /celix/trunk/remote_services/discovery_etcd/private: include/etcd.h src/etcd.c src/etcd_watcher.c

Posted by Alexander Broekhuis <a....@gmail.com>.
2014-10-07 21:37 GMT+02:00 Bjoern Petri <bj...@sundevil.de>:

>
> Alexander, I just added the change for the "update" - could you do a small
> test and verify whether this fixed the broken Amdatu/Celix discovery?
>

This solves the problem. Thanks for the quick fix!

-- 
Met vriendelijke groet,

Alexander Broekhuis

Re: svn commit: r1627454 - in /celix/trunk/remote_services/discovery_etcd/private: include/etcd.h src/etcd.c src/etcd_watcher.c

Posted by Bjoern Petri <bj...@sundevil.de>.
Alexander, I just added the change for the "update" - could you do a 
small test and verify whether this fixed the broken Amdatu/Celix 
discovery?

Regards,
   Bjoern


On 2014-10-07 21:23, Alexander Broekhuis wrote:
> 2014-10-07 20:57 GMT+02:00 Bjoern Petri <bj...@sundevil.de>:
> 
>> 
>>>> Indeed, an "update" would be the nicer solution - this is 
>>>> unfortunately
>>>> not yet supported by the Celix implementation - I will add it within 
>>>> the
>>>> next days.
>>>> 
>>>> We could also change the update interval from 10 seconds, if you'd 
>>>> like
>>>> to. I just choose a value not that high, so I don't need to wait 
>>>> that
>>>> long
>>>> when shutting down the discovery_etcd.
>>>> 
>>>> 
>>> I don't think the solution is in changing a value, because then after 
>>> that
>>> time, the other ends would still toggle all services because of the 
>>> "set",
>>> which should not happen.
>>> 
>> 
>> I think you maybe misunderstood me?! I would propose to implement an
>> "update" (instead of set) and in addition to align the Celix update
>> interval to the Amdatu one.
> 
> 
> Ah ok, I read the change of the interval as a possible workaround/fix, 
> not
> as addition to an "update". And yeah I agree about "update" being a 
> good
> solution. No argument there! :)
> 
>> 
>> 
>>  Looking at the code, a TTL of 0 means no TTL. Is this correct? In 
>> that
>>> case
>>> I can set the TTL to 0.
>>> 
>> 
>> Jep, setting the ttl-argument to 0 will disable the ttl.
> 
> 
> But as mentioned in my other post, this would keep the 
> "addOwnFramework"
> being called, resulting in the extra "set" calls each 10 seconds?
> 
>> 
>> 
>>  If this is not the case, this update breaks interop
>>> with Amdatu, which I think we don't want. Disabling the TTL would be 
>>> a
>>> reasonable fix I guess.
>>> 
>> 
>> Well, in long-term I think also the Amdatu implementation should 
>> change to
>> support ttl, don't you think so?
>> 
> 
> I agree, something like a TTL is needed to keep the setup error-proof 
> wrt
> network issues and even software crashes. But reading the documentation 
> of
> etcd I am a bit confused.
> At [1] it mentions: "NOTE: Keys can only be expired by a cluster 
> leader, so
> if a machine gets disconnected from the cluster, its keys will not 
> expire
> until it rejoins."
> This is not something which I would expect...
> 
> 
> [1]: https://coreos.com/docs/distributed-configuration/etcd-api/

Re: svn commit: r1627454 - in /celix/trunk/remote_services/discovery_etcd/private: include/etcd.h src/etcd.c src/etcd_watcher.c

Posted by Alexander Broekhuis <a....@gmail.com>.
2014-10-07 20:57 GMT+02:00 Bjoern Petri <bj...@sundevil.de>:

>
>>> Indeed, an "update" would be the nicer solution - this is unfortunately
>>> not yet supported by the Celix implementation - I will add it within the
>>> next days.
>>>
>>> We could also change the update interval from 10 seconds, if you'd like
>>> to. I just choose a value not that high, so I don't need to wait that
>>> long
>>> when shutting down the discovery_etcd.
>>>
>>>
>> I don't think the solution is in changing a value, because then after that
>> time, the other ends would still toggle all services because of the "set",
>> which should not happen.
>>
>
> I think you maybe misunderstood me?! I would propose to implement an
> "update" (instead of set) and in addition to align the Celix update
> interval to the Amdatu one.


Ah ok, I read the change of the interval as a possible workaround/fix, not
as addition to an "update". And yeah I agree about "update" being a good
solution. No argument there! :)

>
>
>  Looking at the code, a TTL of 0 means no TTL. Is this correct? In that
>> case
>> I can set the TTL to 0.
>>
>
> Jep, setting the ttl-argument to 0 will disable the ttl.


But as mentioned in my other post, this would keep the "addOwnFramework"
being called, resulting in the extra "set" calls each 10 seconds?

>
>
>  If this is not the case, this update breaks interop
>> with Amdatu, which I think we don't want. Disabling the TTL would be a
>> reasonable fix I guess.
>>
>
> Well, in long-term I think also the Amdatu implementation should change to
> support ttl, don't you think so?
>

I agree, something like a TTL is needed to keep the setup error-proof wrt
network issues and even software crashes. But reading the documentation of
etcd I am a bit confused.
At [1] it mentions: "NOTE: Keys can only be expired by a cluster leader, so
if a machine gets disconnected from the cluster, its keys will not expire
until it rejoins."
This is not something which I would expect...


[1]: https://coreos.com/docs/distributed-configuration/etcd-api/

-- 
Met vriendelijke groet,

Alexander Broekhuis

Re: svn commit: r1627454 - in /celix/trunk/remote_services/discovery_etcd/private: include/etcd.h src/etcd.c src/etcd_watcher.c

Posted by Bjoern Petri <bj...@sundevil.de>.
On 2014-10-07 20:42, Alexander Broekhuis wrote:
> 2014-10-07 20:38 GMT+02:00 Bjoern Petri <bj...@sundevil.de>:
> 
>> 
>>  The Amdatu implementation does not yet support TTL. But is this 
>> behaviour
>>> as expected? I don't think a TTL update should trigger a "set" on the
>>> other
>>> ends..
>>> 
>>> What do you think?
>>> 
>> 
>> Indeed, an "update" would be the nicer solution - this is 
>> unfortunately
>> not yet supported by the Celix implementation - I will add it within 
>> the
>> next days.
>> 
>> We could also change the update interval from 10 seconds, if you'd 
>> like
>> to. I just choose a value not that high, so I don't need to wait that 
>> long
>> when shutting down the discovery_etcd.
>> 
> 
> I don't think the solution is in changing a value, because then after 
> that
> time, the other ends would still toggle all services because of the 
> "set",
> which should not happen.

I think you maybe misunderstood me?! I would propose to implement an 
"update" (instead of set) and in addition to align the Celix update 
interval to the Amdatu one.

> Looking at the code, a TTL of 0 means no TTL. Is this correct? In that 
> case
> I can set the TTL to 0.

Jep, setting the ttl-argument to 0 will disable the ttl.

> If this is not the case, this update breaks interop
> with Amdatu, which I think we don't want. Disabling the TTL would be a
> reasonable fix I guess.

Well, in long-term I think also the Amdatu implementation should change 
to support ttl, don't you think so?

Regards,
   Bjoern

Re: svn commit: r1627454 - in /celix/trunk/remote_services/discovery_etcd/private: include/etcd.h src/etcd.c src/etcd_watcher.c

Posted by Alexander Broekhuis <a....@gmail.com>.
Replying to my own post..

2014-10-07 20:42 GMT+02:00 Alexander Broekhuis <a....@gmail.com>:
>
>
>> Indeed, an "update" would be the nicer solution - this is unfortunately
>> not yet supported by the Celix implementation - I will add it within the
>> next days.
>>
>> We could also change the update interval from 10 seconds, if you'd like
>> to. I just choose a value not that high, so I don't need to wait that long
>> when shutting down the discovery_etcd.
>>
>
> I don't think the solution is in changing a value, because then after that
> time, the other ends would still toggle all services because of the "set",
> which should not happen.
>
> Looking at the code, a TTL of 0 means no TTL. Is this correct? In that
> case I can set the TTL to 0. If this is not the case, this update breaks
> interop with Amdatu, which I think we don't want. Disabling the TTL would
> be a reasonable fix I guess.
>

Not setting a TTL is not enough in this case. The "addOwnFramework" call
should not happen each watch interval. So perhaps this needs some
additional logic.

Since this now breaks the RSA when using it with Amdatu, is this something
that can be added easily? Or is it easier to make it an "update"?

Ps: I need this for tomorrow for a demo, if this is a problem I'll just
revert the TTL changes for a local build..


-- 
Met vriendelijke groet,

Alexander Broekhuis

Re: svn commit: r1627454 - in /celix/trunk/remote_services/discovery_etcd/private: include/etcd.h src/etcd.c src/etcd_watcher.c

Posted by Alexander Broekhuis <a....@gmail.com>.
2014-10-07 20:38 GMT+02:00 Bjoern Petri <bj...@sundevil.de>:

>
>  The Amdatu implementation does not yet support TTL. But is this behaviour
>> as expected? I don't think a TTL update should trigger a "set" on the
>> other
>> ends..
>>
>> What do you think?
>>
>
> Indeed, an "update" would be the nicer solution - this is unfortunately
> not yet supported by the Celix implementation - I will add it within the
> next days.
>
> We could also change the update interval from 10 seconds, if you'd like
> to. I just choose a value not that high, so I don't need to wait that long
> when shutting down the discovery_etcd.
>

I don't think the solution is in changing a value, because then after that
time, the other ends would still toggle all services because of the "set",
which should not happen.

Looking at the code, a TTL of 0 means no TTL. Is this correct? In that case
I can set the TTL to 0. If this is not the case, this update breaks interop
with Amdatu, which I think we don't want. Disabling the TTL would be a
reasonable fix I guess.


-- 
Met vriendelijke groet,

Alexander Broekhuis

Re: svn commit: r1627454 - in /celix/trunk/remote_services/discovery_etcd/private: include/etcd.h src/etcd.c src/etcd_watcher.c

Posted by Bjoern Petri <bj...@sundevil.de>.
On 2014-10-07 20:23, Alexander Broekhuis wrote:
[..]
> @Bjoern
> I did some more digging, and I guess the problem is with how Celix 
> watches
> for changes. After calling the "etcd_watch" 
> "etcdWatcher_addOwnFramework"
> is called, which basically re-adds the values for that discovery (I 
> guess
> to refresh the TTL). But this triggers an update of the value, which in
> turn triggers the watch of the other side with a new set. This result 
> in a
> remove/add of the discovery endpoint.
> This results in the remove/add juggling. The interval is about 10 
> seconds,
> I am not sure where this one comes from.

The interval comes from the curl timeout. The etcd_watch returns with a
timeout if no value has changed.

> The Amdatu implementation does not yet support TTL. But is this 
> behaviour
> as expected? I don't think a TTL update should trigger a "set" on the 
> other
> ends..
> 
> What do you think?

Indeed, an "update" would be the nicer solution - this is unfortunately 
not yet supported by the Celix implementation - I will add it within the 
next days.

We could also change the update interval from 10 seconds, if you'd like 
to. I just choose a value not that high, so I don't need to wait that 
long when shutting down the discovery_etcd.

Regards,
   Bjoern





Re: svn commit: r1627454 - in /celix/trunk/remote_services/discovery_etcd/private: include/etcd.h src/etcd.c src/etcd_watcher.c

Posted by Alexander Broekhuis <a....@gmail.com>.
Hi,

@Isaac: TTL is indeed Time To Live. Etcd uses this to remove a value from
its tree after the TTL. If for example a host goes down, ie crashes, or
network problems, the entry would not be removed from the tree, and other
users could still try to connect to it.
A host has to update its own values within this TTL. Basically this update
means refreshing the TTL, so it start at the max again.

@Bjoern
I did some more digging, and I guess the problem is with how Celix watches
for changes. After calling the "etcd_watch" "etcdWatcher_addOwnFramework"
is called, which basically re-adds the values for that discovery (I guess
to refresh the TTL). But this triggers an update of the value, which in
turn triggers the watch of the other side with a new set. This result in a
remove/add of the discovery endpoint.
This results in the remove/add juggling. The interval is about 10 seconds,
I am not sure where this one comes from.

The Amdatu implementation does not yet support TTL. But is this behaviour
as expected? I don't think a TTL update should trigger a "set" on the other
ends..

What do you think?


2014-10-07 19:11 GMT+02:00 Alexander Broekhuis <a....@gmail.com>:

> Hi,
>
> 2014-10-07 19:05 GMT+02:00 Bjoern Petri <bj...@sundevil.de>:
>>
>>
>> the ttl specifies the specified time to live for the key in seconds. The
>> discovery_etcd announces itself with a ttl of 30 seconds. If the etcd-watch
>> of the amdatu discovery etcd-implementation (not the
>> endpoint_discovery_poller) takes more time than this, the described
>> behavior occurs. Because the etcd-watch is nothing else than a long poll,
>> the timeout values has to be set accordingly. The celix discovery-etcd
>> implementation currently uses 10 seconds for that.
>>
>
> Can we align this to work out of the box with Amdatu? I think there is
> great value in having a working implementation with as little setup as
> possible. If there is a specific reason for the 10 seconds in Celix, we
> need to document this somewhere.
>
> Thanks for the explanation!
>
> --
> Met vriendelijke groet,
>
> Alexander Broekhuis
>



-- 
Met vriendelijke groet,

Alexander Broekhuis

Re: svn commit: r1627454 - in /celix/trunk/remote_services/discovery_etcd/private: include/etcd.h src/etcd.c src/etcd_watcher.c

Posted by Alexander Broekhuis <a....@gmail.com>.
Hi,

2014-10-07 19:05 GMT+02:00 Bjoern Petri <bj...@sundevil.de>:
>
>
> the ttl specifies the specified time to live for the key in seconds. The
> discovery_etcd announces itself with a ttl of 30 seconds. If the etcd-watch
> of the amdatu discovery etcd-implementation (not the
> endpoint_discovery_poller) takes more time than this, the described
> behavior occurs. Because the etcd-watch is nothing else than a long poll,
> the timeout values has to be set accordingly. The celix discovery-etcd
> implementation currently uses 10 seconds for that.
>

Can we align this to work out of the box with Amdatu? I think there is
great value in having a working implementation with as little setup as
possible. If there is a specific reason for the 10 seconds in Celix, we
need to document this somewhere.

Thanks for the explanation!

-- 
Met vriendelijke groet,

Alexander Broekhuis

Re: svn commit: r1627454 - in /celix/trunk/remote_services/discovery_etcd/private: include/etcd.h src/etcd.c src/etcd_watcher.c

Posted by Bjoern Petri <bj...@sundevil.de>.
Hi Alexander,

the ttl specifies the specified time to live for the key in seconds. The 
discovery_etcd announces itself with a ttl of 30 seconds. If the 
etcd-watch of the amdatu discovery etcd-implementation (not the 
endpoint_discovery_poller) takes more time than this, the described 
behavior occurs. Because the etcd-watch is nothing else than a long 
poll, the timeout values has to be set accordingly. The celix 
discovery-etcd implementation currently uses 10 seconds for that.

Regards,
   Bjoern


On 2014-10-07 18:26, Alexander Broekhuis wrote:
> Hi Bjoern,
> 
> I've updated to trunk, and now when I try to run a Celix -> Amdatu 
> example
> using Etcd, it doesn't work as expected.
> I haven't investigated this deeply, but when I disable the TTL code 
> (revert
> the changes from this (and the fix) commit, it works again. So 
> somewhere in
> this part something is going on.
> 
> What happens is that the service is picked up by Amdatu, is added, but
> after some time is removed again. How is the TTL supposed to work? Is 
> this
> a consequence of the Amdatu poller not polling quick enough wrt TTL set 
> in
> Celix?
> 
> Thanks,
> 
> 2014-09-25 6:56 GMT+02:00 <bp...@apache.org>:
> 
>> Author: bpetri
>> Date: Thu Sep 25 04:56:28 2014
>> New Revision: 1627454
>> 
>> URL: http://svn.apache.org/r1627454
>> Log:
>> 
>> CELIX-152: add ttl support for etcd
>> 
>> 
>> Modified:
>>     celix/trunk/remote_services/discovery_etcd/private/include/etcd.h
>>     celix/trunk/remote_services/discovery_etcd/private/src/etcd.c
>>     
>> celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c
>> 
>> Modified: 
>> celix/trunk/remote_services/discovery_etcd/private/include/etcd.h
>> URL:
>> http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_etcd/private/include/etcd.h?rev=1627454&r1=1627453&r2=1627454&view=diff
>> 
>> ==============================================================================
>> --- celix/trunk/remote_services/discovery_etcd/private/include/etcd.h
>> (original)
>> +++ celix/trunk/remote_services/discovery_etcd/private/include/etcd.h 
>> Thu
>> Sep 25 04:56:28 2014
>> @@ -21,7 +21,7 @@
>>  bool etcd_init(char* server, int port);
>>  bool etcd_get(char* key, char* value, char*action, int* 
>> modifiedIndex);
>>  bool etcd_getNodes(char* directory, char** nodeNames, int* size);
>> -bool etcd_set(char* key, char* value);
>> +bool etcd_set(char* key, char* value, int ttl);
>>  bool etcd_del(char* key);
>>  bool etcd_watch(char* key, int index, char* action, char* prevValue,
>> char* value);
>> 
>> 
>> Modified: 
>> celix/trunk/remote_services/discovery_etcd/private/src/etcd.c
>> URL:
>> http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_etcd/private/src/etcd.c?rev=1627454&r1=1627453&r2=1627454&view=diff
>> 
>> ==============================================================================
>> --- celix/trunk/remote_services/discovery_etcd/private/src/etcd.c
>> (original)
>> +++ celix/trunk/remote_services/discovery_etcd/private/src/etcd.c Thu 
>> Sep
>> 25 04:56:28 2014
>> @@ -5,16 +5,17 @@
>>  #include <curl/curl.h>
>>  #include <jansson.h>
>> 
>> -
>> -
>>  #include "etcd.h"
>> 
>> +#define DEFAULT_CURL_TIMEOUT          10
>> +#define DEFAULT_CURL_CONECTTIMEOUT    10
>> +
>>  typedef enum {
>>         GET, PUT, DELETE
>>  } request_t;
>> 
>>  static char* etcd_server = NULL;
>> -static int etcd_port = NULL;
>> +static int etcd_port = 0;
>> 
>>  struct MemoryStruct {
>>         char *memory;
>> @@ -44,8 +45,8 @@ static int performRequest(char* url, req
>>         CURLcode res = 0;
>> 
>>         curl = curl_easy_init();
>> -       curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
>> -       curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
>> +       curl_easy_setopt(curl, CURLOPT_TIMEOUT, DEFAULT_CURL_TIMEOUT);
>> +       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);
>> @@ -175,7 +176,7 @@ bool etcd_getNodes(char* directory, char
>>  }
>> 
>>  //set
>> -bool etcd_set(char* key, char* value) {
>> +bool etcd_set(char* key, char* value, int ttl) {
>>         json_error_t error;
>>         json_t* js_root;
>>         json_t* js_node;
>> @@ -190,7 +191,11 @@ bool etcd_set(char* key, char* value) {
>>         reply.size = 0; /* no data at this point */
>> 
>>         snprintf(url, MAX_URL_LENGTH, "http://%s:%d/v2/keys/%s",
>> etcd_server, etcd_port, key);
>> -       snprintf(request, MAX_CONTENT_LENGTH, "value=%s", value);
>> +
>> +       if (ttl > 0)
>> +           snprintf(request, MAX_CONTENT_LENGTH, "value=%s", value);
>> +       else
>> +           snprintf(request, MAX_CONTENT_LENGTH, "value=%s;ttl=%d",
>> value, ttl);
>> 
>>         res = performRequest(url, PUT, WriteMemoryCallback, request,
>> (void*) &reply);
>>         if (res == CURLE_OPERATION_TIMEDOUT) {
>> 
>> Modified:
>> celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c
>> URL:
>> http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c?rev=1627454&r1=1627453&r2=1627454&view=diff
>> 
>> ==============================================================================
>> --- 
>> celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c
>> (original)
>> +++ 
>> celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c
>> Thu Sep 25 04:56:28 2014
>> @@ -53,6 +53,10 @@ struct etcd_watcher {
>>  #define CFG_ETCD_SERVER_PORT   "DISCOVERY_ETCD_SERVER_PORT"
>>  #define DEFAULT_ETCD_SERVER_PORT 4001
>> 
>> +// be careful - this should be higher than the curl timeout
>> +#define CFG_ETCD_TTL   "DISCOVERY_ETCD_TTL"
>> +#define DEFAULT_ETCD_TTL 30
>> +
>> 
>>  // note that the rootNode shouldn't have a leading slash
>>  static celix_status_t etcdWatcher_getRootPath(char* rootNode) {
>> @@ -132,6 +136,49 @@ static celix_status_t etcdWatcher_addAlr
>>         return status;
>>  }
>> 
>> +
>> +static celix_status_t etcdWatcher_addOwnFramework(bundle_context_pt
>> context)
>> +{
>> +    celix_status_t status = CELIX_BUNDLE_EXCEPTION;
>> +    char localNodePath[MAX_LOCALNODE_LENGTH];
>> +    char* endpoints = NULL;
>> +    char* ttlStr = NULL;
>> +    int ttl;
>> +
>> +    // register own framework
>> +    if ((status = etcdWatcher_getLocalNodePath(context,
>> &localNodePath[0])) != CELIX_SUCCESS) {
>> +        return status;
>> +    }
>> +
>> +    if ((bundleContext_getProperty(context, DISCOVERY_POLL_ENDPOINTS,
>> &endpoints) != CELIX_SUCCESS) || !endpoints) {
>> +        endpoints = DEFAULT_POLL_ENDPOINTS;
>> +    }
>> +
>> +    if ((bundleContext_getProperty(context, CFG_ETCD_TTL, &ttlStr) !=
>> CELIX_SUCCESS) || !ttlStr) {
>> +        ttl = DEFAULT_ETCD_TTL;
>> +    }
>> +    else
>> +    {
>> +        char* endptr = ttlStr;
>> +        errno = 0;
>> +        ttl =  strtol(ttlStr, &endptr, 10);
>> +        if (*endptr || errno != 0) {
>> +            ttl = DEFAULT_ETCD_TTL;
>> +        }
>> +    }
>> +
>> +    if (etcd_set(localNodePath, endpoints, ttl) == false)
>> +    {
>> +        fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Cannot register 
>> local
>> discovery");
>> +    }
>> +    else
>> +    {
>> +        status = CELIX_SUCCESS;
>> +    }
>> +
>> +    return status;
>> +}
>> +
>>  /*
>>   * performs (blocking) etcd_watch calls to check for
>>   * changing discovery endpoint information within etcd.
>> @@ -161,6 +208,8 @@ static void* etcdWatcher_run(void* data)
>>                                 fw_log(logger, 
>> OSGI_FRAMEWORK_LOG_INFO,
>> "Unexpected action: %s", action);
>>                         }
>>                 }
>> +               // update own framework uuid in any case;
>> +           etcdWatcher_addOwnFramework(watcher->context);
>>         }
>> 
>>         return NULL;
>> @@ -174,11 +223,10 @@ celix_status_t etcdWatcher_create(endpoi
>>                 etcd_watcher_pt *watcher)
>>  {
>>         celix_status_t status = CELIX_SUCCESS;
>> -       char localNodePath[MAX_LOCALNODE_LENGTH];
>> +
>>         char* etcd_server = NULL;
>>         char* etcd_port_string = NULL;
>> -       int etcd_port = NULL;
>> -       char* endpoints = NULL;
>> +       int etcd_port = 0;
>> 
>>         if (poller == NULL) {
>>                 return CELIX_BUNDLE_EXCEPTION;
>> @@ -211,9 +259,6 @@ celix_status_t etcdWatcher_create(endpoi
>>                 }
>>         }
>> 
>> -       if ((bundleContext_getProperty(context, 
>> DISCOVERY_POLL_ENDPOINTS,
>> &endpoints) != CELIX_SUCCESS) || !endpoints) {
>> -               endpoints = DEFAULT_POLL_ENDPOINTS;
>> -       }
>> 
>> 
>>         if (etcd_init(etcd_server, etcd_port) == false)
>> @@ -221,17 +266,7 @@ celix_status_t etcdWatcher_create(endpoi
>>                 return CELIX_BUNDLE_EXCEPTION;
>>         }
>> 
>> -       // register own framework
>> -       if ((status = etcdWatcher_getLocalNodePath(context,
>> &localNodePath[0])) != CELIX_SUCCESS) {
>> -               return status;
>> -       }
>> -
>> -       if (etcd_set(localNodePath, endpoints) == false)
>> -       {
>> -               fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Cannot
>> register local discovery");
>> -       }
>> -
>> -
>> +       etcdWatcher_addOwnFramework(context);
>> 
>>         if ((status = 
>> celixThreadMutex_create(&(*watcher)->watcherLock,
>> NULL)) != CELIX_SUCCESS) {
>>                 return status;
>> 
>> 
>> 

Re: svn commit: r1627454 - in /celix/trunk/remote_services/discovery_etcd/private: include/etcd.h src/etcd.c src/etcd_watcher.c

Posted by Alexander Broekhuis <a....@gmail.com>.
Hi Bjoern,

I've updated to trunk, and now when I try to run a Celix -> Amdatu example
using Etcd, it doesn't work as expected.
I haven't investigated this deeply, but when I disable the TTL code (revert
the changes from this (and the fix) commit, it works again. So somewhere in
this part something is going on.

What happens is that the service is picked up by Amdatu, is added, but
after some time is removed again. How is the TTL supposed to work? Is this
a consequence of the Amdatu poller not polling quick enough wrt TTL set in
Celix?

Thanks,

2014-09-25 6:56 GMT+02:00 <bp...@apache.org>:

> Author: bpetri
> Date: Thu Sep 25 04:56:28 2014
> New Revision: 1627454
>
> URL: http://svn.apache.org/r1627454
> Log:
>
> CELIX-152: add ttl support for etcd
>
>
> Modified:
>     celix/trunk/remote_services/discovery_etcd/private/include/etcd.h
>     celix/trunk/remote_services/discovery_etcd/private/src/etcd.c
>     celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c
>
> Modified: celix/trunk/remote_services/discovery_etcd/private/include/etcd.h
> URL:
> http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_etcd/private/include/etcd.h?rev=1627454&r1=1627453&r2=1627454&view=diff
>
> ==============================================================================
> --- celix/trunk/remote_services/discovery_etcd/private/include/etcd.h
> (original)
> +++ celix/trunk/remote_services/discovery_etcd/private/include/etcd.h Thu
> Sep 25 04:56:28 2014
> @@ -21,7 +21,7 @@
>  bool etcd_init(char* server, int port);
>  bool etcd_get(char* key, char* value, char*action, int* modifiedIndex);
>  bool etcd_getNodes(char* directory, char** nodeNames, int* size);
> -bool etcd_set(char* key, char* value);
> +bool etcd_set(char* key, char* value, int ttl);
>  bool etcd_del(char* key);
>  bool etcd_watch(char* key, int index, char* action, char* prevValue,
> char* value);
>
>
> Modified: celix/trunk/remote_services/discovery_etcd/private/src/etcd.c
> URL:
> http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_etcd/private/src/etcd.c?rev=1627454&r1=1627453&r2=1627454&view=diff
>
> ==============================================================================
> --- celix/trunk/remote_services/discovery_etcd/private/src/etcd.c
> (original)
> +++ celix/trunk/remote_services/discovery_etcd/private/src/etcd.c Thu Sep
> 25 04:56:28 2014
> @@ -5,16 +5,17 @@
>  #include <curl/curl.h>
>  #include <jansson.h>
>
> -
> -
>  #include "etcd.h"
>
> +#define DEFAULT_CURL_TIMEOUT          10
> +#define DEFAULT_CURL_CONECTTIMEOUT    10
> +
>  typedef enum {
>         GET, PUT, DELETE
>  } request_t;
>
>  static char* etcd_server = NULL;
> -static int etcd_port = NULL;
> +static int etcd_port = 0;
>
>  struct MemoryStruct {
>         char *memory;
> @@ -44,8 +45,8 @@ static int performRequest(char* url, req
>         CURLcode res = 0;
>
>         curl = curl_easy_init();
> -       curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
> -       curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
> +       curl_easy_setopt(curl, CURLOPT_TIMEOUT, DEFAULT_CURL_TIMEOUT);
> +       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);
> @@ -175,7 +176,7 @@ bool etcd_getNodes(char* directory, char
>  }
>
>  //set
> -bool etcd_set(char* key, char* value) {
> +bool etcd_set(char* key, char* value, int ttl) {
>         json_error_t error;
>         json_t* js_root;
>         json_t* js_node;
> @@ -190,7 +191,11 @@ bool etcd_set(char* key, char* value) {
>         reply.size = 0; /* no data at this point */
>
>         snprintf(url, MAX_URL_LENGTH, "http://%s:%d/v2/keys/%s",
> etcd_server, etcd_port, key);
> -       snprintf(request, MAX_CONTENT_LENGTH, "value=%s", value);
> +
> +       if (ttl > 0)
> +           snprintf(request, MAX_CONTENT_LENGTH, "value=%s", value);
> +       else
> +           snprintf(request, MAX_CONTENT_LENGTH, "value=%s;ttl=%d",
> value, ttl);
>
>         res = performRequest(url, PUT, WriteMemoryCallback, request,
> (void*) &reply);
>         if (res == CURLE_OPERATION_TIMEDOUT) {
>
> Modified:
> celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c
> URL:
> http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c?rev=1627454&r1=1627453&r2=1627454&view=diff
>
> ==============================================================================
> --- celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c
> (original)
> +++ celix/trunk/remote_services/discovery_etcd/private/src/etcd_watcher.c
> Thu Sep 25 04:56:28 2014
> @@ -53,6 +53,10 @@ struct etcd_watcher {
>  #define CFG_ETCD_SERVER_PORT   "DISCOVERY_ETCD_SERVER_PORT"
>  #define DEFAULT_ETCD_SERVER_PORT 4001
>
> +// be careful - this should be higher than the curl timeout
> +#define CFG_ETCD_TTL   "DISCOVERY_ETCD_TTL"
> +#define DEFAULT_ETCD_TTL 30
> +
>
>  // note that the rootNode shouldn't have a leading slash
>  static celix_status_t etcdWatcher_getRootPath(char* rootNode) {
> @@ -132,6 +136,49 @@ static celix_status_t etcdWatcher_addAlr
>         return status;
>  }
>
> +
> +static celix_status_t etcdWatcher_addOwnFramework(bundle_context_pt
> context)
> +{
> +    celix_status_t status = CELIX_BUNDLE_EXCEPTION;
> +    char localNodePath[MAX_LOCALNODE_LENGTH];
> +    char* endpoints = NULL;
> +    char* ttlStr = NULL;
> +    int ttl;
> +
> +    // register own framework
> +    if ((status = etcdWatcher_getLocalNodePath(context,
> &localNodePath[0])) != CELIX_SUCCESS) {
> +        return status;
> +    }
> +
> +    if ((bundleContext_getProperty(context, DISCOVERY_POLL_ENDPOINTS,
> &endpoints) != CELIX_SUCCESS) || !endpoints) {
> +        endpoints = DEFAULT_POLL_ENDPOINTS;
> +    }
> +
> +    if ((bundleContext_getProperty(context, CFG_ETCD_TTL, &ttlStr) !=
> CELIX_SUCCESS) || !ttlStr) {
> +        ttl = DEFAULT_ETCD_TTL;
> +    }
> +    else
> +    {
> +        char* endptr = ttlStr;
> +        errno = 0;
> +        ttl =  strtol(ttlStr, &endptr, 10);
> +        if (*endptr || errno != 0) {
> +            ttl = DEFAULT_ETCD_TTL;
> +        }
> +    }
> +
> +    if (etcd_set(localNodePath, endpoints, ttl) == false)
> +    {
> +        fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Cannot register local
> discovery");
> +    }
> +    else
> +    {
> +        status = CELIX_SUCCESS;
> +    }
> +
> +    return status;
> +}
> +
>  /*
>   * performs (blocking) etcd_watch calls to check for
>   * changing discovery endpoint information within etcd.
> @@ -161,6 +208,8 @@ static void* etcdWatcher_run(void* data)
>                                 fw_log(logger, OSGI_FRAMEWORK_LOG_INFO,
> "Unexpected action: %s", action);
>                         }
>                 }
> +               // update own framework uuid in any case;
> +           etcdWatcher_addOwnFramework(watcher->context);
>         }
>
>         return NULL;
> @@ -174,11 +223,10 @@ celix_status_t etcdWatcher_create(endpoi
>                 etcd_watcher_pt *watcher)
>  {
>         celix_status_t status = CELIX_SUCCESS;
> -       char localNodePath[MAX_LOCALNODE_LENGTH];
> +
>         char* etcd_server = NULL;
>         char* etcd_port_string = NULL;
> -       int etcd_port = NULL;
> -       char* endpoints = NULL;
> +       int etcd_port = 0;
>
>         if (poller == NULL) {
>                 return CELIX_BUNDLE_EXCEPTION;
> @@ -211,9 +259,6 @@ celix_status_t etcdWatcher_create(endpoi
>                 }
>         }
>
> -       if ((bundleContext_getProperty(context, DISCOVERY_POLL_ENDPOINTS,
> &endpoints) != CELIX_SUCCESS) || !endpoints) {
> -               endpoints = DEFAULT_POLL_ENDPOINTS;
> -       }
>
>
>         if (etcd_init(etcd_server, etcd_port) == false)
> @@ -221,17 +266,7 @@ celix_status_t etcdWatcher_create(endpoi
>                 return CELIX_BUNDLE_EXCEPTION;
>         }
>
> -       // register own framework
> -       if ((status = etcdWatcher_getLocalNodePath(context,
> &localNodePath[0])) != CELIX_SUCCESS) {
> -               return status;
> -       }
> -
> -       if (etcd_set(localNodePath, endpoints) == false)
> -       {
> -               fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Cannot
> register local discovery");
> -       }
> -
> -
> +       etcdWatcher_addOwnFramework(context);
>
>         if ((status = celixThreadMutex_create(&(*watcher)->watcherLock,
> NULL)) != CELIX_SUCCESS) {
>                 return status;
>
>
>


-- 
Met vriendelijke groet,

Alexander Broekhuis