From bd6a491cf212e1bb75bd5ded16dde2d15187b770 Mon Sep 17 00:00:00 2001 From: yiyiyimu Date: Fri, 10 Jul 2020 15:31:54 +0800 Subject: [PATCH 1/8] implement lease related func and test files --- lib/resty/etcd/v3.lua | 88 ++++++++++++++++++++++ t/v3/lease.t | 166 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 254 insertions(+) create mode 100644 t/v3/lease.t diff --git a/lib/resty/etcd/v3.lua b/lib/resty/etcd/v3.lua index ea55d53b..91d14e13 100644 --- a/lib/resty/etcd/v3.lua +++ b/lib/resty/etcd/v3.lua @@ -634,6 +634,94 @@ local function watch(self, key, attr) return callback_fun end +local function grant(self, ttl, id) + if ttl==nil then + return nil, "lease grant command needs TTL argument" + end + + if not typeof.int(ttl) then + return nil, 'ttl must be integer' + end + + id = id or 0 + local opts = { + body = { + TTL = ttl, + ID = id + }, + } + + return _request_uri(self, "POST", + choose_endpoint(self).full_prefix .. "/lease/grant", opts) +end + +local function revoke(self, id) + if id==nil then + return nil, "lease revoke command needs ID argument" + end + + local opts = { + body = { + ID = id + }, + } + + return _request_uri(self, "POST", + choose_endpoint(self).full_prefix .. "/lease/revoke", opts) +end + +local function timetolive(self, id, keys) + if id==nil then + return nil, "lease timetolive command needs ID argument" + end + + keys = keys or false + local opts = { + body = { + ID = id, + keys = keys + }, + } + + return _request_uri(self, "POST", + choose_endpoint(self).full_prefix .. "/lease/timetolive", opts) +end + +local function keepalive(self, id) + if id==nil then + return nil, "lease keepalive command needs ID argument" + end + + local opts = { + body = { + ID = id + }, + } + + return _request_uri(self, "POST", + choose_endpoint(self).full_prefix .. "/lease/keepalive", opts) +end + +function _M.grant(self, ttl, id) + return grant(self, ttl, id) +end + +function _M.revoke(self, id) + return revoke(self, id) +end + +function _M.keepalive(self, id) + return keepalive(self, id) +end + +function _M.timetolive(self, id, keys) + return timetolive(self, id, keys) +end + +function _M.leases(self) + return _request_uri(self, "POST", + choose_endpoint(self).full_prefix .. "/lease/leases") +end do local attr = {} diff --git a/t/v3/lease.t b/t/v3/lease.t new file mode 100644 index 00000000..dfc6cbf3 --- /dev/null +++ b/t/v3/lease.t @@ -0,0 +1,166 @@ +use Test::Nginx::Socket::Lua; + +log_level('info'); +no_long_string(); +repeat_each(1); + +#todo +#test multi-leases +#test multi-keys conbined to one lease + +my $etcd_version = `etcd --version`; +if ($etcd_version =~ /^etcd Version: 2/ || $etcd_version =~ /^etcd Version: 3.1./) { + plan(skip_all => "etcd is too old, skip v3 protocol"); +} else { + plan 'no_plan'; +} + +our $HttpConfig = <<'_EOC_'; + lua_socket_log_errors off; + lua_package_path 'lib/?.lua;/usr/local/share/lua/5.3/?.lua;/usr/share/lua/5.1/?.lua;;'; + init_by_lua_block { + function check_res(data, err, val, status) + if err then + ngx.say("err: ", err) + ngx.exit(200) + end + + if val then + if data.body.kvs==nil then + ngx.exit(404) + end + if data.body.kvs and val ~= data.body.kvs[1].value then + ngx.say("failed to check value") + ngx.log(ngx.ERR, "failed to check value, got: ", data.body.kvs[1].value, + ", expect: ", val) + ngx.exit(200) + else + ngx.say("checked val as expect: ", val) + end + end + + if status and status ~= data.status then + ngx.exit(data.status) + end + end + } +_EOC_ + +run_tests(); + +__DATA__ + +=== TEST 1: lease grant, leases(), and wait for expiring +--- http_config eval: $::HttpConfig +--- config + location /t { + content_by_lua_block { + local etcd, err = require "resty.etcd".new({protocol = "v3"}) + check_res(etcd, err) + + local res, err = etcd:grant(2) + check_res(res, err) + + local data, err = etcd:leases() + if data.body.leases[1].ID ~= res.body.ID then + ngx.say("leases not working") + end + + local data, err = etcd:set("/test", "abc", {prev_kv = true, lease = res.body.ID}) + check_res(data, err) + + local data, err = etcd:get("/test") + check_res(data, err, "abc") + + ngx.sleep(2.5) + + local data, err = etcd:get("/test") + if data.body.kvs == nil then + ngx.say("key expired as expect") + end + } + } +--- request +GET /t +--- no_error_log +[error] +--- response_body +checked val as expect: abc +key expired as expect + + +=== TEST 2: lease grant and revoke +--- http_config eval: $::HttpConfig +--- config + location /t { + content_by_lua_block { + local etcd, err = require "resty.etcd".new({protocol = "v3"}) + check_res(etcd, err) + + local res, err = etcd:grant(5) + check_res(res, err) + + local data, err = etcd:set("/test", "abc", {prev_kv = true, lease = res.body.ID}) + check_res(data, err) + + local data, err = etcd:get("/test") + check_res(data, err, "abc") + + local data, err = etcd:revoke(res.body.ID) + check_res(data, err) + + local data, err = etcd:get("/test") + if data.body.kvs == nil then + ngx.say("deleted key as expect") + end + } + } +--- request +GET /t +--- no_error_log +[error] +--- response_body +checked val as expect: abc +deleted key as expect + +=== TEST 3: lease grant and keealive +--- http_config eval: $::HttpConfig +--- config + location /t { + content_by_lua_block { + local etcd, err = require "resty.etcd".new({protocol = "v3"}) + check_res(etcd, err) + + local res, err = etcd:grant(5) + check_res(res, err) + + local data, err = etcd:set("/test", "abc", {prev_kv = true, lease = res.body.ID}) + check_res(data, err) + + local data, err = etcd:get("/test") + check_res(data, err, "abc") + + local data, err = etcd:timetolive(res.body.ID) + check_res(data, err) + + ngx.sleep(1) + if tonumber(data.body.TTL) < 5 then + ngx.say("current TTL decreased") + end + + local data, err = etcd:keepalive(res.body.ID) + check_res(data, err) + + if data.body.result.TTL == "5" then + ngx.say("renewed TTL") + end + } + } +--- request +GET /t +--- no_error_log +[error] +--- response_body +checked val as expect: abc +current TTL decreased +renewed TTL From 4d080b01e75bab51de40b9476ff1ae9e9f069d2c Mon Sep 17 00:00:00 2001 From: yiyiyimu Date: Fri, 10 Jul 2020 15:54:58 +0800 Subject: [PATCH 2/8] add lease documentation --- api_v3.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ t/v3/lease.t | 1 + 2 files changed, 57 insertions(+) diff --git a/api_v3.md b/api_v3.md index 446bdec4..577269b1 100644 --- a/api_v3.md +++ b/api_v3.md @@ -15,6 +15,11 @@ API V3 * [rmdir](#rmdir) * [txn](#txn) * [version](#version) + * [grant](#grant) + * [revoke](#revoke) + * [keepalive](#keepalive) + * [timetolive](#timetolive) + * [leases](#leases) Method ====== @@ -261,3 +266,54 @@ local res, err = cli:txn(compare, success, nil) Gets the etcd version info. [Back to TOP](#api-v3) + +### grant + +`syntax: res, err = cli:grant(TTL:int [, ID:int])` + +- `TTL`: advisory time-to-live in seconds. +- `ID`: the requested ID for the lease. If ID is set to 0, the lessor chooses an ID. + +Creates a lease which expires if the server does not receive a keepalive within a given time to live period. All keys attached to the lease will be expired and deleted if the lease expires. Each expired key generates a delete event in the event history. + +[Back to TOP](#api-v3) + +### revoke + +`syntax: res, err = cli:revoke(ID:int)` + +- `ID`: the lease ID to revoke. When the ID is revoked, all associated keys will be deleted. + +Revokes a lease. All keys attached to the lease will expire and be deleted. + +[Back to TOP](#api-v3) + +### keepalive + +`syntax: res, err = cli:keepalive(ID:int)` + +- `ID`: the lease ID for the lease to keep alive. + +Keeps the lease alive by streaming keep alive requests from the client to the server and streaming keep alive responses from the server to the client. + +[Back to TOP](#api-v3) + +### timetolive + +`syntax: res, err = cli:timetolive(ID:int [, keys: bool])` + +- `ID`: the lease ID for the lease. +- `keys`: if true, query all the keys attached to this lease. + +Retrieves lease information. + +[Back to TOP](#api-v3) + +### leases + +`syntax: res, err = cli:leases()` + +Lists all existing leases. + +[Back to TOP](#api-v3) + diff --git a/t/v3/lease.t b/t/v3/lease.t index dfc6cbf3..12da0515 100644 --- a/t/v3/lease.t +++ b/t/v3/lease.t @@ -7,6 +7,7 @@ repeat_each(1); #todo #test multi-leases #test multi-keys conbined to one lease +#test the keys conbined to timetolive is the same to granted (some kind of decoding needed) my $etcd_version = `etcd --version`; if ($etcd_version =~ /^etcd Version: 2/ || $etcd_version =~ /^etcd Version: 3.1./) { From a4d2888e7983b1742b5e6aee63ed7558800ee781 Mon Sep 17 00:00:00 2001 From: yiyiyimu Date: Fri, 10 Jul 2020 15:59:52 +0800 Subject: [PATCH 3/8] fix naming typo of txn test file --- t/v3/{tnx.t => txn.t} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename t/v3/{tnx.t => txn.t} (100%) diff --git a/t/v3/tnx.t b/t/v3/txn.t similarity index 100% rename from t/v3/tnx.t rename to t/v3/txn.t From 4189a1637ccae8233b121f3a7db51786a2796d95 Mon Sep 17 00:00:00 2001 From: yiyiyimu Date: Fri, 10 Jul 2020 17:14:33 +0800 Subject: [PATCH 4/8] remove extra layer and fix formatting --- lib/resty/etcd/v3.lua | 162 +++++++++++++++++++----------------------- t/v3/lease.t | 3 + 2 files changed, 76 insertions(+), 89 deletions(-) diff --git a/lib/resty/etcd/v3.lua b/lib/resty/etcd/v3.lua index 91d14e13..c9127c8f 100644 --- a/lib/resty/etcd/v3.lua +++ b/lib/resty/etcd/v3.lua @@ -634,95 +634,6 @@ local function watch(self, key, attr) return callback_fun end -local function grant(self, ttl, id) - if ttl==nil then - return nil, "lease grant command needs TTL argument" - end - - if not typeof.int(ttl) then - return nil, 'ttl must be integer' - end - - id = id or 0 - local opts = { - body = { - TTL = ttl, - ID = id - }, - } - - return _request_uri(self, "POST", - choose_endpoint(self).full_prefix .. "/lease/grant", opts) -end - -local function revoke(self, id) - if id==nil then - return nil, "lease revoke command needs ID argument" - end - - local opts = { - body = { - ID = id - }, - } - - return _request_uri(self, "POST", - choose_endpoint(self).full_prefix .. "/lease/revoke", opts) -end - -local function timetolive(self, id, keys) - if id==nil then - return nil, "lease timetolive command needs ID argument" - end - - keys = keys or false - local opts = { - body = { - ID = id, - keys = keys - }, - } - - return _request_uri(self, "POST", - choose_endpoint(self).full_prefix .. "/lease/timetolive", opts) -end - -local function keepalive(self, id) - if id==nil then - return nil, "lease keepalive command needs ID argument" - end - - local opts = { - body = { - ID = id - }, - } - - return _request_uri(self, "POST", - choose_endpoint(self).full_prefix .. "/lease/keepalive", opts) -end - -function _M.grant(self, ttl, id) - return grant(self, ttl, id) -end - -function _M.revoke(self, id) - return revoke(self, id) -end - -function _M.keepalive(self, id) - return keepalive(self, id) -end - -function _M.timetolive(self, id, keys) - return timetolive(self, id, keys) -end - -function _M.leases(self) - return _request_uri(self, "POST", - choose_endpoint(self).full_prefix .. "/lease/leases") -end - do local attr = {} function _M.get(self, key, opts) @@ -913,6 +824,79 @@ function _M.txn(self, compare, success, failure, opts) return txn(self, opts, compare, success, failure) end +function _M.grant(self, ttl, id) + if ttl == nil then + return nil, "lease grant command needs TTL argument" + end + + if not typeof.int(ttl) then + return nil, 'ttl must be integer' + end + + id = id or 0 + local opts = { + body = { + TTL = ttl, + ID = id + }, + } + + return _request_uri(self, "POST", + choose_endpoint(self).full_prefix .. "/lease/grant", opts) +end + +function _M.revoke(self, id) + if id == nil then + return nil, "lease revoke command needs ID argument" + end + + local opts = { + body = { + ID = id + }, + } + + return _request_uri(self, "POST", + choose_endpoint(self).full_prefix .. "/lease/revoke", opts) +end + +function _M.keepalive(self, id) + if id == nil then + return nil, "lease keepalive command needs ID argument" + end + + local opts = { + body = { + ID = id + }, + } + + return _request_uri(self, "POST", + choose_endpoint(self).full_prefix .. "/lease/keepalive", opts) +end + +function _M.timetolive(self, id, keys) + if id == nil then + return nil, "lease timetolive command needs ID argument" + end + + keys = keys or false + local opts = { + body = { + ID = id, + keys = keys + }, + } + + return _request_uri(self, "POST", + choose_endpoint(self).full_prefix .. "/lease/timetolive", opts) +end + +function _M.leases(self) + return _request_uri(self, "POST", + choose_endpoint(self).full_prefix .. "/lease/leases") +end + -- /version function _M.version(self) diff --git a/t/v3/lease.t b/t/v3/lease.t index 12da0515..0a0b3a40 100644 --- a/t/v3/lease.t +++ b/t/v3/lease.t @@ -90,6 +90,7 @@ checked val as expect: abc key expired as expect + === TEST 2: lease grant and revoke --- http_config eval: $::HttpConfig --- config @@ -124,6 +125,8 @@ GET /t checked val as expect: abc deleted key as expect + + === TEST 3: lease grant and keealive --- http_config eval: $::HttpConfig --- config From 314e20008edf95e88f2a6d64c99610bfab892f3f Mon Sep 17 00:00:00 2001 From: yiyiyimu Date: Sat, 11 Jul 2020 20:34:45 +0800 Subject: [PATCH 5/8] multiversion adaptation --- lib/resty/etcd/v3.lua | 4 +- t/v3/lease.t | 7 +--- t/v3/lease3.4.t | 85 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 t/v3/lease3.4.t diff --git a/lib/resty/etcd/v3.lua b/lib/resty/etcd/v3.lua index c9127c8f..5afc9b64 100644 --- a/lib/resty/etcd/v3.lua +++ b/lib/resty/etcd/v3.lua @@ -857,7 +857,7 @@ function _M.revoke(self, id) } return _request_uri(self, "POST", - choose_endpoint(self).full_prefix .. "/lease/revoke", opts) + choose_endpoint(self).full_prefix .. "/kv/lease/revoke", opts) end function _M.keepalive(self, id) @@ -889,7 +889,7 @@ function _M.timetolive(self, id, keys) } return _request_uri(self, "POST", - choose_endpoint(self).full_prefix .. "/lease/timetolive", opts) + choose_endpoint(self).full_prefix .. "/kv/lease/timetolive", opts) end function _M.leases(self) diff --git a/t/v3/lease.t b/t/v3/lease.t index 0a0b3a40..9336392e 100644 --- a/t/v3/lease.t +++ b/t/v3/lease.t @@ -51,7 +51,7 @@ run_tests(); __DATA__ -=== TEST 1: lease grant, leases(), and wait for expiring +=== TEST 1: lease grant, and wait for expiring --- http_config eval: $::HttpConfig --- config location /t { @@ -62,11 +62,6 @@ __DATA__ local res, err = etcd:grant(2) check_res(res, err) - local data, err = etcd:leases() - if data.body.leases[1].ID ~= res.body.ID then - ngx.say("leases not working") - end - local data, err = etcd:set("/test", "abc", {prev_kv = true, lease = res.body.ID}) check_res(data, err) diff --git a/t/v3/lease3.4.t b/t/v3/lease3.4.t new file mode 100644 index 00000000..9a06f14f --- /dev/null +++ b/t/v3/lease3.4.t @@ -0,0 +1,85 @@ +use Test::Nginx::Socket::Lua; + +log_level('info'); +no_long_string(); +repeat_each(1); + +#todo +#test multi-leases +#test multi-keys conbined to one lease +#test the keys conbined to timetolive is the same to granted (some kind of decoding needed) + +my $etcd_version = `etcd --version`; +if ($etcd_version =~ /^etcd Version: 2/ || $etcd_version =~ /^etcd Version: 3.1./ || $etcd_version =~ /^etcd Version: 3.2./ || $etcd_version =~ /^etcd Version: 3.3./) { + plan(skip_all => "test by another lease test"); +} else { + plan 'no_plan'; +} + +our $HttpConfig = <<'_EOC_'; + lua_socket_log_errors off; + lua_package_path 'lib/?.lua;/usr/local/share/lua/5.3/?.lua;/usr/share/lua/5.1/?.lua;;'; + init_by_lua_block { + function check_res(data, err, val, status) + if err then + ngx.say("err: ", err) + ngx.exit(200) + end + + if val then + if data.body.kvs==nil then + ngx.exit(404) + end + if data.body.kvs and val ~= data.body.kvs[1].value then + ngx.say("failed to check value") + ngx.log(ngx.ERR, "failed to check value, got: ", data.body.kvs[1].value, + ", expect: ", val) + ngx.exit(200) + else + ngx.say("checked val as expect: ", val) + end + end + + if status and status ~= data.status then + ngx.exit(data.status) + end + end + } +_EOC_ + +run_tests(); + +__DATA__ + +=== TEST 1: lease grant, leases(), and wait for expiring +--- http_config eval: $::HttpConfig +--- config + location /t { + content_by_lua_block { + local etcd, err = require "resty.etcd".new({protocol = "v3"}) + check_res(etcd, err) + + local res, err = etcd:grant(2) + check_res(res, err) + + local data, err = etcd:set("/test", "abc", {prev_kv = true, lease = res.body.ID}) + check_res(data, err) + + local data, err = etcd:get("/test") + check_res(data, err, "abc") + + ngx.sleep(2.5) + + local data, err = etcd:get("/test") + if data.body.kvs == nil then + ngx.say("key expired as expect") + end + } + } +--- request +GET /t +--- no_error_log +[error] +--- response_body +checked val as expect: abc +key expired as expect From f3a5928706c2a3696cad1b81eef3e70c75cc922c Mon Sep 17 00:00:00 2001 From: yiyiyimu Date: Sun, 12 Jul 2020 17:13:51 +0800 Subject: [PATCH 6/8] improved test file --- lib/resty/etcd/v3.lua | 18 +++++++--- t/v3/lease.t | 78 ++++++++++++++++++++++++++++++------------- t/v3/lease3.4.t | 11 +++++- 3 files changed, 78 insertions(+), 29 deletions(-) diff --git a/lib/resty/etcd/v3.lua b/lib/resty/etcd/v3.lua index 5afc9b64..647c3d5d 100644 --- a/lib/resty/etcd/v3.lua +++ b/lib/resty/etcd/v3.lua @@ -383,8 +383,8 @@ local function get(self, key, attr) choose_endpoint(self).full_prefix .. "/kv/range", opts, attr and attr.timeout or self.timeout) - if res and res.status==200 then - if res.body.kvs and tab_nkeys(res.body.kvs)>0 then + if res and res.status == 200 then + if res.body.kvs and tab_nkeys(res.body.kvs) > 0 then for _, kv in ipairs(res.body.kvs) do kv.key = decode_base64(kv.key) kv.value = decode_base64(kv.value) @@ -429,7 +429,7 @@ local function txn(self, opts_arg, compare, success, failure) return nil, "compare couldn't be empty" end - if (success==nil or #success < 1) and (failure==nil or #failure<1) then + if (success == nil or #success < 1) and (failure == nil or #failure < 1) then return nil, "success and failure couldn't be empty at the same time" end @@ -888,8 +888,18 @@ function _M.timetolive(self, id, keys) }, } - return _request_uri(self, "POST", + local res, err = _request_uri(self, "POST", choose_endpoint(self).full_prefix .. "/kv/lease/timetolive", opts) + + if res and res.status == 200 then + if res.body.keys and tab_nkeys(res.body.keys) > 0 then + for i, key in ipairs(res.body.keys) do + res.body.keys[i] = decode_base64(key) + end + end + end + + return res, err end function _M.leases(self) diff --git a/t/v3/lease.t b/t/v3/lease.t index 9336392e..2f8b0a42 100644 --- a/t/v3/lease.t +++ b/t/v3/lease.t @@ -4,11 +4,6 @@ log_level('info'); no_long_string(); repeat_each(1); -#todo -#test multi-leases -#test multi-keys conbined to one lease -#test the keys conbined to timetolive is the same to granted (some kind of decoding needed) - my $etcd_version = `etcd --version`; if ($etcd_version =~ /^etcd Version: 2/ || $etcd_version =~ /^etcd Version: 3.1./) { plan(skip_all => "etcd is too old, skip v3 protocol"); @@ -68,8 +63,11 @@ __DATA__ local data, err = etcd:get("/test") check_res(data, err, "abc") - ngx.sleep(2.5) + ngx.sleep(1) + local data, err = etcd:get("/test") + check_res(data, err, "abc") + ngx.sleep(1.5) -- till lease expired local data, err = etcd:get("/test") if data.body.kvs == nil then ngx.say("key expired as expect") @@ -82,6 +80,7 @@ GET /t [error] --- response_body checked val as expect: abc +checked val as expect: abc key expired as expect @@ -94,21 +93,31 @@ key expired as expect local etcd, err = require "resty.etcd".new({protocol = "v3"}) check_res(etcd, err) - local res, err = etcd:grant(5) + local res, err = etcd:grant(2) check_res(res, err) - local data, err = etcd:set("/test", "abc", {prev_kv = true, lease = res.body.ID}) + local data, err = etcd:set("/test1", "abc", {prev_kv = true, lease = res.body.ID}) check_res(data, err) - local data, err = etcd:get("/test") + local data, err = etcd:set("/test2", "bcd", {prev_kv = true, lease = res.body.ID}) + check_res(data, err) + + local data, err = etcd:get("/test1") check_res(data, err, "abc") + local data, err = etcd:get("/test2") + check_res(data, err, "bcd") + local data, err = etcd:revoke(res.body.ID) check_res(data, err) - local data, err = etcd:get("/test") - if data.body.kvs == nil then + local data1, err1 = etcd:get("/test1") + local data2, err2 = etcd:get("/test2") + if data1.body.kvs == nil and data2.body.kvs == nil then ngx.say("deleted key as expect") + else + ngx.say("failed to delete key") + ngx.exit(200) end } } @@ -118,6 +127,7 @@ GET /t [error] --- response_body checked val as expect: abc +checked val as expect: bcd deleted key as expect @@ -130,29 +140,49 @@ deleted key as expect local etcd, err = require "resty.etcd".new({protocol = "v3"}) check_res(etcd, err) - local res, err = etcd:grant(5) + local res, err = etcd:grant(2, 123) check_res(res, err) - local data, err = etcd:set("/test", "abc", {prev_kv = true, lease = res.body.ID}) + local res, err = etcd:grant(2, 456) + check_res(res, err) + + local data, err = etcd:set("/test1", "abc", {prev_kv = true, lease = 123}) check_res(data, err) - local data, err = etcd:get("/test") + local data, err = etcd:set("/test2", "bcd", {prev_kv = true, lease = 456}) + check_res(data, err) + + local data, err = etcd:get("/test1") check_res(data, err, "abc") - local data, err = etcd:timetolive(res.body.ID) - check_res(data, err) + local data, err = etcd:get("/test2") + check_res(data, err, "bcd") - ngx.sleep(1) - if tonumber(data.body.TTL) < 5 then - ngx.say("current TTL decreased") + local data, err = etcd:timetolive(123, true) + check_res(data, err) + if data.body.keys then + if data.body.keys[1] ~= "/test1" then + ngx.say("lease attached keys are not as expected: ", data.body.keys) + end end - local data, err = etcd:keepalive(res.body.ID) + ngx.sleep(1) + local data, err = etcd:keepalive(123) check_res(data, err) + + ngx.sleep(1.5) + + local data, err = etcd:get("/test1") + if data.body.kvs == nil then + ngx.say("Keepalive failed") + end - if data.body.result.TTL == "5" then - ngx.say("renewed TTL") + local data, err = etcd:get("/test2") + if data.body.kvs ~= nil then + ngx.say("Wrong lease got keepalived") end + + ngx.say("all done") } } --- request @@ -161,5 +191,5 @@ GET /t [error] --- response_body checked val as expect: abc -current TTL decreased -renewed TTL +checked val as expect: bcd +all done diff --git a/t/v3/lease3.4.t b/t/v3/lease3.4.t index 9a06f14f..9ef20e2c 100644 --- a/t/v3/lease3.4.t +++ b/t/v3/lease3.4.t @@ -62,14 +62,22 @@ __DATA__ local res, err = etcd:grant(2) check_res(res, err) + local data, err = etcd:leases() + if data.body.leases[1].ID ~= res.body.ID then + ngx.say("leases not working") + end + local data, err = etcd:set("/test", "abc", {prev_kv = true, lease = res.body.ID}) check_res(data, err) local data, err = etcd:get("/test") check_res(data, err, "abc") - ngx.sleep(2.5) + ngx.sleep(1) + local data, err = etcd:get("/test") + check_res(data, err, "abc") + ngx.sleep(1.5) -- till lease expired local data, err = etcd:get("/test") if data.body.kvs == nil then ngx.say("key expired as expect") @@ -82,4 +90,5 @@ GET /t [error] --- response_body checked val as expect: abc +checked val as expect: abc key expired as expect From 9e2c0186e338ad40f13e47db842cc0f1d68c4e10 Mon Sep 17 00:00:00 2001 From: yiyiyimu Date: Sun, 12 Jul 2020 17:37:33 +0800 Subject: [PATCH 7/8] same with #12 --- t/v2/dir.t | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/t/v2/dir.t b/t/v2/dir.t index 30e23dca..f3f86b93 100644 --- a/t/v2/dir.t +++ b/t/v2/dir.t @@ -218,7 +218,7 @@ checked val as expect: b end) cur_time = ngx.now() - res, err = etcd:waitdir("/dir", res.body.node.modifiedIndex + 1, 5) + res, err = etcd:waitdir("/dir", res.body.node.modifiedIndex + 1, 3) check_res(res, err, "a") ngx.say("wait more than 1sec: ", ngx.now() - cur_time > 1) @@ -233,6 +233,7 @@ checked [/dir] is dir. err: timeout, more than 1sec: true checked val as expect: a wait more than 1sec: true +--- timeout: 5 From 261536278e0bff880a9f46d214ac95b40b196d38 Mon Sep 17 00:00:00 2001 From: yiyiyimu Date: Sun, 12 Jul 2020 20:05:47 +0800 Subject: [PATCH 8/8] add demo in doc --- api_v3.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/api_v3.md b/api_v3.md index 577269b1..8e8bbc78 100644 --- a/api_v3.md +++ b/api_v3.md @@ -63,7 +63,7 @@ Please refer the **etcd API documentaion** at - https://github.com/coreos/etcd f Gets the value for key. ```lua -local res, err = cli:get('/path_/to/_key') +local res, err = cli:get('/path/to/key') ``` [Back to TOP](#api-v3) @@ -276,6 +276,14 @@ Gets the etcd version info. Creates a lease which expires if the server does not receive a keepalive within a given time to live period. All keys attached to the lease will be expired and deleted if the lease expires. Each expired key generates a delete event in the event history. +```lua +-- grant a lease with 5 second TTL +local res, err = cli:grant(5) + +-- attach key to lease, whose ID would be contained in res +local data, err = etcd:set('/path/to/key', 'val', {lease = res.body.ID}) +``` + [Back to TOP](#api-v3) ### revoke @@ -286,6 +294,15 @@ Creates a lease which expires if the server does not receive a keepalive within Revokes a lease. All keys attached to the lease will expire and be deleted. +```lua +local res, err = cli:grant(5) +local data, err = etcd:set('/path/to/key', 'val', {lease = res.body.ID}) + +local data, err = etcd:revoke(res.body.ID) +local data, err = cli:get('/path/to/key') +-- responce would contains no kvs +``` + [Back to TOP](#api-v3) ### keepalive