Skip to content

Commit f681068

Browse files
authored
bugfix: fixed get_range_end bug, add watch key="" means fetch all (#70)
fix etcd v3 watch dir bug add watch key="" empty case, mean watch all key change
1 parent 1ead4be commit f681068

File tree

6 files changed

+110
-29
lines changed

6 files changed

+110
-29
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Name
33

44
[resty-etcd](https://github.com/iresty/lua-resty-etcd) Nonblocking Lua etcd driver library for OpenResty, this module supports etcd API v2 and v3.
55

6-
[![Build Status](https://travis-ci.org/iresty/lua-resty-etcd.svg?branch=master)](https://travis-ci.org/iresty/lua-resty-etcd)
6+
[![Build Status](https://travis-ci.org/api7/lua-resty-etcd.svg?branch=master)](https://travis-ci.org/api7/lua-resty-etcd)
77
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/iresty/lua-resty-etcd/blob/master/LICENSE)
88

99
Table of Contents

lib/resty/etcd/utils.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,13 @@ local function log_info( ... )
9292
end
9393
_M.log_info = log_info
9494

95+
local function verify_key(key)
96+
if not key or #key == 0 then
97+
return false, "key should not be empty"
98+
end
99+
return true, nil
100+
end
101+
_M.verify_key = verify_key
102+
95103

96104
return _M

lib/resty/etcd/v3.lua

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -226,15 +226,16 @@ function refresh_jwt_token(self)
226226
return true, nil
227227
end
228228

229+
230+
229231
local function set(self, key, val, attr)
230232
-- verify key
231-
key = utils.normalize(key)
232-
if key == '/' then
233-
return nil, "key should not be a slash"
233+
local _, err = utils.verify_key(key)
234+
if err then
235+
return nil, err
234236
end
235237

236238
key = encode_base64(key)
237-
local err
238239
val, err = encode_json_base64(val)
239240
if not val then
240241
return nil, err
@@ -291,10 +292,11 @@ local function set(self, key, val, attr)
291292
end
292293

293294
local function get(self, key, attr)
295+
294296
-- verify key
295-
key = utils.normalize(key)
296-
if not key or key == '/' then
297-
return nil, "key invalid"
297+
local _, err = utils.verify_key(key)
298+
if err then
299+
return nil, err
298300
end
299301

300302
attr = attr or {}
@@ -542,31 +544,24 @@ end
542544

543545

544546
local function get_range_end(key)
545-
local last = sub_str(key, -1)
546-
key = sub_str(key, 1, #key-1)
547-
local has_slash = false
548-
if last == '/' then
549-
last = sub_str(key, -1)
550-
key = sub_str(key, 1, #key-1)
551-
has_slash = true
547+
if #key == 0 then
548+
return str_char(0)
552549
end
553550

554-
if key == '/' then
555-
return nil, "invalid key"
556-
end
551+
local last = sub_str(key, -1)
552+
key = sub_str(key, 1, #key-1)
557553

558554
local ascii = str_byte(last) + 1
559555
local str = str_char(ascii)
560556

561-
return key .. str .. (has_slash and '/' or '')
557+
return key .. str
562558
end
563559

564560

565561
local function watch(self, key, attr)
566562
-- verify key
567-
key = utils.normalize(key)
568-
if key == '/' then
569-
return nil, "key should not be a slash"
563+
if #key == 0 then
564+
key = str_char(0)
570565
end
571566

572567
key = encode_base64(key)

t/v2/dir.t

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ checked val as expect: b
221221
res, err = etcd:waitdir("/dir", res.body.node.modifiedIndex + 1, 3)
222222

223223
check_res(res, err, "a")
224-
ngx.say("wait more than 1sec: ", ngx.now() - cur_time > 1)
224+
ngx.update_time()
225+
ngx.say("wait more than 1sec: ", ngx.now() - cur_time >= 1)
225226
}
226227
}
227228
--- request

t/v2/key.t

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,8 @@ checked val as expect: abc
225225
226226
local cur_time = ngx.now()
227227
local res2, err = etcd:wait("/test", res.body.node.modifiedIndex + 1, 1)
228-
ngx.say("err: ", err, ", more than 1sec: ", ngx.now() - cur_time > 1)
228+
ngx.update_time()
229+
ngx.say("err: ", err, ", more than 1sec: ", ngx.now() - cur_time >= 1)
229230

230231
ngx.timer.at(1.5, function ()
231232
etcd:set("/test", "bcd")
@@ -234,7 +235,8 @@ checked val as expect: abc
234235
cur_time = ngx.now()
235236
res, err = etcd:wait("/test", res.body.node.modifiedIndex + 1, 3)
236237
check_res(res, err, "bcd")
237-
ngx.say("wait more than 1sec: ", ngx.now() - cur_time > 1)
238+
ngx.update_time()
239+
ngx.say("wait more than 1sec: ", ngx.now() - cur_time >= 1)
238240
}
239241
}
240242
--- request

t/v3/key.t

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ our $HttpConfig = <<'_EOC_';
2424
end
2525
2626
if val then
27-
if data.body.kvs==nil then
27+
if data and data.body.kvs==nil then
2828
ngx.exit(404)
2929
end
30-
if data.body.kvs and val ~= data.body.kvs[1].value then
30+
if data and data.body.kvs and val ~= data.body.kvs[1].value then
3131
ngx.say("failed to check value")
3232
ngx.log(ngx.ERR, "failed to check value, got: ", data.body.kvs[1].value,
3333
", expect: ", val)
@@ -61,6 +61,12 @@ __DATA__
6161
6262
local data, err = etcd:get("/test")
6363
check_res(data, err, "abc")
64+
65+
local data, err = etcd:get("")
66+
check_res(data, nil, err)
67+
68+
local data, err = etcd:set("")
69+
check_res(data, nil, err)
6470
}
6571
}
6672
--- request
@@ -69,6 +75,8 @@ GET /t
6975
[error]
7076
--- response_body
7177
checked val as expect: abc
78+
checked val as expect: key should not be empty
79+
checked val as expect: key should not be empty
7280
7381
7482
@@ -166,8 +174,12 @@ timeout/
166174
local res, err = etcd:set("/wdir", "abc")
167175
check_res(res, err)
168176
177+
ngx.timer.at(0.05, function ()
178+
etcd:set("/wdir-", "bcd3")
179+
end)
180+
169181
ngx.timer.at(0.1, function ()
170-
etcd:set("/wdir", "bcd4")
182+
etcd:set("/wdir/", "bcd4")
171183
end)
172184
173185
ngx.timer.at(0.2, function ()
@@ -179,7 +191,7 @@ timeout/
179191
end)
180192
181193
local cur_time = ngx.now()
182-
local body_chunk_fun, err = etcd:watchdir("/wdir", {timeout = 1.5})
194+
local body_chunk_fun, err = etcd:watchdir("/wdir/", {timeout = 1.5})
183195
if not body_chunk_fun then
184196
ngx.say("failed to watch: ", err)
185197
end
@@ -213,6 +225,69 @@ timeout/
213225
--- timeout: 5
214226
215227
228+
=== TEST 4.1: watchdir(key=="")
229+
--- http_config eval: $::HttpConfig
230+
--- config
231+
location /t {
232+
content_by_lua_block {
233+
local etcd, err = require("resty.etcd").new({protocol = "v3"})
234+
check_res(etcd, err)
235+
236+
local res, err = etcd:set("/wdir", "abc")
237+
check_res(res, err)
238+
239+
ngx.timer.at(0.05, function ()
240+
etcd:set("/wdir-", "bcd3")
241+
end)
242+
243+
ngx.timer.at(0.1, function ()
244+
etcd:set("/wdir/", "bcd4")
245+
end)
246+
247+
ngx.timer.at(0.2, function ()
248+
etcd:set("/wdir/a", "bcd4a")
249+
end)
250+
251+
ngx.timer.at(0.3, function ()
252+
etcd:delete("/wdir/a")
253+
end)
254+
255+
local cur_time = ngx.now()
256+
local body_chunk_fun, err = etcd:watchdir("", {timeout = 1.5})
257+
if not body_chunk_fun then
258+
ngx.say("failed to watch: ", err)
259+
end
260+
261+
local idx = 0
262+
while true do
263+
local chunk, err = body_chunk_fun()
264+
265+
if not chunk then
266+
if err then
267+
ngx.say(err)
268+
end
269+
break
270+
end
271+
272+
idx = idx + 1
273+
ngx.say(idx, ": ", require("cjson").encode(chunk.result))
274+
end
275+
}
276+
}
277+
--- request
278+
GET /t
279+
--- no_error_log
280+
[error]
281+
--- response_body_like eval
282+
qr/1:.*"created":true.*
283+
2:.*"value":"bcd3".*
284+
3:.*"value":"bcd4".*
285+
4:.*"value":"bcd4a".*
286+
5:.*"type":"DELETE".*
287+
timeout/
288+
--- timeout: 5
289+
290+
216291
217292
=== TEST 5: setx(key, val) failed
218293
--- http_config eval: $::HttpConfig

0 commit comments

Comments
 (0)