Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: implemented new lease-related api #66

Merged
merged 8 commits into from
Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 74 additions & 1 deletion api_v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ API V3
* [rmdir](#rmdir)
* [txn](#txn)
* [version](#version)
* [grant](#grant)
* [revoke](#revoke)
* [keepalive](#keepalive)
* [timetolive](#timetolive)
* [leases](#leases)

Method
======
Expand Down Expand Up @@ -58,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)
Expand Down Expand Up @@ -261,3 +266,71 @@ 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.

```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

`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.

```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

`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)

90 changes: 86 additions & 4 deletions lib/resty/etcd/v3.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -634,7 +634,6 @@ local function watch(self, key, attr)
return callback_fun
end


do
local attr = {}
function _M.get(self, key, opts)
Expand Down Expand Up @@ -825,6 +824,89 @@ 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 .. "/kv/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
},
}

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)
return _request_uri(self, "POST",
choose_endpoint(self).full_prefix .. "/lease/leases")
end


-- /version
function _M.version(self)
Expand Down
3 changes: 2 additions & 1 deletion t/v2/dir.t
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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



Expand Down
Loading