diff --git a/.travis.yml b/.travis.yml index 734c7a0..0d94694 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ addons: - luarocks services: - - redis + - docker cache: directories: @@ -74,5 +74,6 @@ script: - ngx-build $NGINX_VERSION --with-ipv6 --with-http_realip_module --with-http_ssl_module --add-module=../echo-nginx-module --add-module=../lua-nginx-module --add-module=../stream-lua-nginx-module --with-stream --with-stream_ssl_module --with-debug - nginx -V - ldd `which nginx`|grep -E 'luajit|ssl|pcre' + - docker run -d -p 6379:6379 --rm --name redis-redisbloom redislabs/rebloom:latest - TEST_SUBSYSTEM=http prove -r t - TEST_SUBSYSTEM=stream prove -r t diff --git a/README.markdown b/README.markdown index d57b180..37061ed 100644 --- a/README.markdown +++ b/README.markdown @@ -569,6 +569,42 @@ Then the output will be [Back to TOC](#table-of-contents) +Redis Module +================== + +This library supports the Redis module. Here is an example with RedisBloom module: + +```lua + local cjson = require "cjson" + local redis = require "resty.redis" + -- register the module prefix "bf" for RedisBloom + redis.register_module_prefix("bf") + + local red = redis:new() + + local ok, err = red:connect("127.0.0.1", 6379) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + -- call BF.ADD command with the prefix 'bf' + res, err = red:bf():add("dog", 1) + if not res then + ngx.say(err) + return + end + ngx.say("receive: ", cjson.encode(res)) + + -- call BF.EXISTS command + res, err = red:bf():exists("dog") + if not res then + ngx.say(err) + return + end + ngx.say("receive: ", cjson.encode(res)) +``` + Load Balancing and Failover =========================== diff --git a/lib/resty/redis.lua b/lib/resty/redis.lua index 114f71f..c954e6f 100644 --- a/lib/resty/redis.lua +++ b/lib/resty/redis.lua @@ -67,6 +67,14 @@ function _M.new(self) end +function _M.register_module_prefix(mod) + _M[mod] = function(self) + self._module_prefix = mod + return self + end +end + + function _M.set_timeout(self, timeout) local sock = rawget(self, "_sock") if not sock then @@ -399,12 +407,23 @@ function _M.read_reply(self) end +local function do_cmd(self, cmd, ...) + local module_prefix = rawget(self, "_module_prefix") + if module_prefix then + self._module_prefix = nil + return _do_cmd(self, module_prefix .. "." .. cmd, ...) + end + + return _do_cmd(self, cmd, ...) +end + + for i = 1, #common_cmds do local cmd = common_cmds[i] _M[cmd] = function (self, ...) - return _do_cmd(self, cmd, ...) + return do_cmd(self, cmd, ...) end end @@ -539,7 +558,7 @@ end setmetatable(_M, {__index = function(self, cmd) local method = function (self, ...) - return _do_cmd(self, cmd, ...) + return do_cmd(self, cmd, ...) end -- cache the lazily generated method in our diff --git a/t/count.t b/t/count.t index a1c98f4..91b6c40 100644 --- a/t/count.t +++ b/t/count.t @@ -22,6 +22,6 @@ __DATA__ ngx.say("size: ", n) '; --- response_body -size: 55 +size: 56 --- no_error_log [error] diff --git a/t/module.t b/t/module.t new file mode 100644 index 0000000..55d5f37 --- /dev/null +++ b/t/module.t @@ -0,0 +1,81 @@ +# vim:set ft= ts=4 sw=4 et: + +use t::Test; + +repeat_each(2); + +plan tests => repeat_each() * (3 * blocks()); + +run_tests(); + +__DATA__ + +=== TEST 1: sanity +--- global_config eval: $::GlobalConfig +--- server_config + content_by_lua_block { + local cjson = require "cjson" + local redis = require "resty.redis" + redis.register_module_prefix("bf") + redis.register_module_prefix("test") + + local red = redis:new() + + local ok, err = red:connect("127.0.0.1", $TEST_NGINX_REDIS_PORT) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + local res, err = red:del("module_1") + if not res then + ngx.say(err) + return + end + + res, err = red:bf():add("module_1", 1) + if not res then + ngx.say(err) + return + end + ngx.say("receive: ", cjson.encode(res)) + + res, err = red:bf():exists("module_1", 1) + if not res then + ngx.say(err) + return + end + ngx.say("receive: ", cjson.encode(res)) + + -- call normal command + res, err = red:del("module_1") + if not res then + ngx.say(err) + return + end + ngx.say("receive: ", cjson.encode(res)) + + -- call cached 'exists' again + res, err = red:exists("module_1") + if not res then + ngx.say(err) + return + end + ngx.say("receive: ", cjson.encode(res)) + + -- call pre-created 'get' method + res, err = red:test():get() + if not res then + ngx.say(err) + end + + red:close() + } +--- response_body_like +receive: 1 +receive: 1 +receive: 1 +receive: 0 +ERR unknown command `test.get`.+ +--- no_error_log +[error]