In CreateTakeoverRequest(), if the initial attempt fails,
then the takeover_request is created without a lease.

Furthermore, when the takeover_request result is set,
it is being set without a lease, and the takeover_request
is not automatically removed.

Add <timeout> parameter to KeyValue::Set, and remove
default value for the <timeout> parameter to KeyValue::Create to
ensure a timeout is always set.
---
 src/osaf/consensus/consensus.cc         | 10 +++---
 src/osaf/consensus/key_value.cc         | 11 +++---
 src/osaf/consensus/key_value.h          |  8 +++--
 src/osaf/consensus/plugins/etcd3.plugin | 48 ++++++++++++++++++++-----
 4 files changed, 57 insertions(+), 20 deletions(-)

diff --git a/src/osaf/consensus/consensus.cc b/src/osaf/consensus/consensus.cc
index 1136c3724..112af7df0 100644
--- a/src/osaf/consensus/consensus.cc
+++ b/src/osaf/consensus/consensus.cc
@@ -181,11 +181,11 @@ bool Consensus::IsWritable() const {
   SaAisErrorT rc;
   uint32_t retries = 0;
   constexpr uint32_t kMaxTestRetry = 3;
-  rc = KeyValue::Set(kTestKeyname, base::Conf::NodeName());
+  rc = KeyValue::Set(kTestKeyname, base::Conf::NodeName(), 0);
   while (rc != SA_AIS_OK && retries < kMaxTestRetry) {
     ++retries;
     std::this_thread::sleep_for(kSleepInterval);
-    rc = KeyValue::Set(kTestKeyname, base::Conf::NodeName());
+    rc = KeyValue::Set(kTestKeyname, base::Conf::NodeName(), 0);
   }
 
   if (rc == SA_AIS_OK) {
@@ -338,7 +338,8 @@ SaAisErrorT Consensus::CreateTakeoverRequest(const 
std::string& current_owner,
   while (rc == SA_AIS_ERR_FAILED_OPERATION && retries < kMaxRetry) {
     ++retries;
     std::this_thread::sleep_for(kSleepInterval);
-    rc = KeyValue::Create(kTakeoverRequestKeyname, takeover_request);
+    rc = KeyValue::Create(kTakeoverRequestKeyname, takeover_request,
+                          takeover_valid_time);
   }
 
   if (rc == SA_AIS_ERR_EXIST) {
@@ -435,7 +436,8 @@ SaAisErrorT Consensus::WriteTakeoverResult(
 
   // previous value must match
   rc =
-      KeyValue::Set(kTakeoverRequestKeyname, takeover_result, 
takeover_request);
+      KeyValue::Set(kTakeoverRequestKeyname, takeover_result,
+                    takeover_request, takeover_valid_time);
 
   return rc;
 }
diff --git a/src/osaf/consensus/key_value.cc b/src/osaf/consensus/key_value.cc
index cf5c02213..109cf9f69 100644
--- a/src/osaf/consensus/key_value.cc
+++ b/src/osaf/consensus/key_value.cc
@@ -58,13 +58,14 @@ SaAisErrorT KeyValue::Get(const std::string& key, 
std::string& value) {
   }
 }
 
-SaAisErrorT KeyValue::Set(const std::string& key, const std::string& value) {
+SaAisErrorT KeyValue::Set(const std::string& key, const std::string& value,
+                          const unsigned int timeout) {
   TRACE_ENTER();
 
   const std::string kv_store_cmd =
       base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
   const std::string command(kv_store_cmd + " set \"" + key + "\" \"" + value +
-                            "\"");
+                            "\" " + std::to_string(timeout));
   std::string output;
   int rc = KeyValue::Execute(command, output);
 
@@ -76,11 +77,13 @@ SaAisErrorT KeyValue::Set(const std::string& key, const 
std::string& value) {
 }
 
 SaAisErrorT KeyValue::Set(const std::string& key, const std::string& value,
-                          const std::string& prev_value) {
+                          const std::string& prev_value,
+                          const unsigned int timeout) {
   const std::string kv_store_cmd =
       base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
   const std::string command(kv_store_cmd + " set_if_prev \"" + key + "\" \"" +
-                            value + "\" \"" + prev_value + "\"");
+                            value + "\" \"" + prev_value +
+                            "\" " + std::to_string(timeout));
   std::string output;
   int rc = KeyValue::Execute(command, output);
 
diff --git a/src/osaf/consensus/key_value.h b/src/osaf/consensus/key_value.h
index af9717595..043a964ae 100644
--- a/src/osaf/consensus/key_value.h
+++ b/src/osaf/consensus/key_value.h
@@ -30,15 +30,17 @@ class KeyValue {
   static SaAisErrorT Get(const std::string& key, std::string& value);
 
   // Set key to value
-  static SaAisErrorT Set(const std::string& key, const std::string& value);
+  static SaAisErrorT Set(const std::string& key, const std::string& value,
+                         const unsigned int timeout);
 
   // Set key to value only if prev value matches
   static SaAisErrorT Set(const std::string& key, const std::string& value,
-                         const std::string& prev_value);
+                         const std::string& prev_value,
+                         const unsigned int timeout);
 
   // Create key, and set to value. Fails if key already exists.
   static SaAisErrorT Create(const std::string& key, const std::string& value,
-                            const unsigned int timeout = 0);
+                            const unsigned int timeout);
 
   // Erase key
   static SaAisErrorT Erase(const std::string& key);
diff --git a/src/osaf/consensus/plugins/etcd3.plugin 
b/src/osaf/consensus/plugins/etcd3.plugin
index 75ef8bb15..b3814c937 100644
--- a/src/osaf/consensus/plugins/etcd3.plugin
+++ b/src/osaf/consensus/plugins/etcd3.plugin
@@ -60,15 +60,30 @@ get() {
 # params:
 #   $1 - <key>
 #   $2 - <value>
+#   $3 - <timeout>
 # returns:
 #   0 - success
 #   non-zero - failure
 setkey() {
   readonly key="$1"
   readonly value="$2"
+  readonly timeout="$3"
+
+  if [ $timeout -gt 0 ]; then
+    # create lease
+    if output=$(etcdctl $etcd_options --dial-timeout $etcd_timeout lease grant 
$timeout)
+    then
+      lease_id=$(echo $output | awk '{print $2}')
+      lease_param="--lease="$lease_id""
+    else
+      return 2
+    fi
+  else
+    lease_param=""
+  fi
 
   if etcdctl $etcd_options --dial-timeout $etcd_timeout put "$directory$key" \
-    "$value" >/dev/null
+    "$value" "$lease_param" >/dev/null
   then
     return 0
   else
@@ -131,6 +146,7 @@ create_key() {
 #   $1 - <key>
 #   $2 - <value>
 #   $3 - <prev>
+#   $4 - <timeout>
 # returns:
 #   0 - success
 #   non-zero - failure
@@ -138,11 +154,25 @@ setkey_match_prev() {
   readonly key="$1"
   readonly value="$2"
   readonly prev="$3"
+  readonly timeout="$4"
 
-  # key already exists, make sure it's empty
+  if [ $timeout -gt 0 ]; then
+    # create lease
+    if output=$(etcdctl $etcd_options --dial-timeout $etcd_timeout lease grant 
$timeout)
+    then
+      lease_id=$(echo $output | awk '{print $2}')
+      lease_param="--lease="$lease_id""
+    else
+      return 2
+    fi
+  else
+    lease_param=""
+  fi
+
+  # key already exists
   transaction="value(\""$directory$key"\") = \"$prev\"
 
-    put \""$directory$key"\" \""$value"\"
+    put \""$directory$key"\" \""$value"\" "$lease_param"
 
   "
   output=$(etcdctl $etcd_options --dial-timeout $etcd_timeout txn <<< 
"$transaction")
@@ -313,19 +343,19 @@ case "$1" in
     exit $?
     ;;
   set)
-    if [ "$#" -ne 3 ]; then
-      echo "Usage: $0 set <key> <value>"
+    if [ "$#" -ne 4 ]; then
+      echo "Usage: $0 set <key> <value> <timeout>"
       exit 1
     fi
-    setkey "$2" "$3"
+    setkey "$2" "$3" "$4"
     exit $?
     ;;
   set_if_prev)
-    if [ "$#" -ne 4 ]; then
-      echo "Usage: $0 set <key> <value> <previous_value>"
+    if [ "$#" -ne 5 ]; then
+      echo "Usage: $0 set <key> <value> <previous_value> <timeout>"
       exit 1
     fi
-    setkey_match_prev "$2" "$3" "$4"
+    setkey_match_prev "$2" "$3" "$4" "$5"
     exit $?
     ;;
   create)
-- 
2.17.1



_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to