diff options
author | Andrew Lewis <nerf@judo.za.org> | 2017-05-23 12:37:43 +0200 |
---|---|---|
committer | Andrew Lewis <nerf@judo.za.org> | 2017-05-23 12:37:43 +0200 |
commit | f859b29631cca0986f3d7423a50c224a28a9404e (patch) | |
tree | 13002e3c79f8b375890b5945821079524dd56637 /lualib/lua_redis.lua | |
parent | 89515c1da8691fd9c7c4d913324a49be50512cc1 (diff) | |
download | rspamd-f859b29631cca0986f3d7423a50c224a28a9404e.tar.gz rspamd-f859b29631cca0986f3d7423a50c224a28a9404e.zip |
[Minor] Split global functions into libraries
Diffstat (limited to 'lualib/lua_redis.lua')
-rw-r--r-- | lualib/lua_redis.lua | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/lualib/lua_redis.lua b/lualib/lua_redis.lua new file mode 100644 index 000000000..1b73f0e8f --- /dev/null +++ b/lualib/lua_redis.lua @@ -0,0 +1,245 @@ +local logger = require "rspamd_logger" + +local exports = {} + +-- This function parses redis server definition using either +-- specific server string for this module or global +-- redis section +local function rspamd_parse_redis_server(module_name) + + local result = {} + local default_port = 6379 + local default_timeout = 1.0 + local upstream_list = require "rspamd_upstream_list" + + local function try_load_redis_servers(options) + -- Try to get read servers: + local upstreams_read, upstreams_write + + if options['read_servers'] then + upstreams_read = upstream_list.create(rspamd_config, + options['read_servers'], default_port) + elseif options['servers'] then + upstreams_read = upstream_list.create(rspamd_config, + options['servers'], default_port) + elseif options['server'] then + upstreams_read = upstream_list.create(rspamd_config, + options['server'], default_port) + end + + if upstreams_read then + if options['write_servers'] then + upstreams_write = upstream_list.create(rspamd_config, + options['write_servers'], default_port) + else + upstreams_write = upstreams_read + end + end + + -- Store options + if not result['timeout'] then + if options['timeout'] then + result['timeout'] = tonumber(options['timeout']) + else + result['timeout'] = default_timeout + end + end + + if options['prefix'] and not result['prefix'] then + result['prefix'] = options['prefix'] + end + if not result['db'] then + if options['db'] then + result['db'] = options['db'] + elseif options['dbname'] then + result['db'] = options['dbname'] + end + end + if options['password'] and not result['password'] then + result['password'] = options['password'] + end + + if upstreams_write and upstreams_read then + result.read_servers = upstreams_read + result.write_servers = upstreams_write + + return true + end + + return false + end + + -- Try local options + local opts = rspamd_config:get_all_opt(module_name) + local ret = false + + if opts then + ret = try_load_redis_servers(opts, result) + end + + if ret then + return result + end + + -- Try global options + opts = rspamd_config:get_all_opt('redis') + + if opts then + if opts[module_name] then + ret = try_load_redis_servers(opts[module_name], result) + if ret then + return result + end + else + ret = try_load_redis_servers(opts, result) + + -- Exclude disabled + if opts['disabled_modules'] then + for _,v in ipairs(opts['disabled_modules']) do + if v == module_name then + logger.infox(rspamd_config, "NOT using default redis server for module %s: it is disabled", + module_name) + + return nil + end + end + end + + if ret then + logger.infox(rspamd_config, "using default redis server for module %s", + module_name) + end + end + end + + if result.read_servers then + return result + else + return nil + end +end + +exports.rspamd_parse_redis_server = rspamd_parse_redis_server +exports.parse_redis_server = rspamd_parse_redis_server + +-- Performs async call to redis hiding all complexity inside function +-- task - rspamd_task +-- redis_params - valid params returned by rspamd_parse_redis_server +-- key - key to select upstream or nil to select round-robin/master-slave +-- is_write - true if need to write to redis server +-- callback - function to be called upon request is completed +-- command - redis command +-- args - table of arguments +local function rspamd_redis_make_request(task, redis_params, key, is_write, callback, command, args) + local addr + local function rspamd_redis_make_request_cb(err, data) + if err then + addr:fail() + else + addr:ok() + end + callback(err, data, addr) + end + if not task or not redis_params or not callback or not command then + return false,nil,nil + end + + local rspamd_redis = require "rspamd_redis" + + if key then + if is_write then + addr = redis_params['write_servers']:get_upstream_by_hash(key) + else + addr = redis_params['read_servers']:get_upstream_by_hash(key) + end + else + if is_write then + addr = redis_params['write_servers']:get_upstream_master_slave(key) + else + addr = redis_params['read_servers']:get_upstream_round_robin(key) + end + end + + if not addr then + logger.errx(task, 'cannot select server to make redis request') + end + + local options = { + task = task, + callback = rspamd_redis_make_request_cb, + host = addr:get_addr(), + timeout = redis_params['timeout'], + cmd = command, + args = args + } + + if redis_params['password'] then + options['password'] = redis_params['password'] + end + + if redis_params['db'] then + options['dbname'] = redis_params['db'] + end + + local ret,conn = rspamd_redis.make_request(options) + return ret,conn,addr +end + +exports.rspamd_redis_make_request = rspamd_redis_make_request +exports.redis_make_request = rspamd_redis_make_request + +local function redis_make_request_taskless(ev_base, cfg, redis_params, key, is_write, callback, command, args) + if not ev_base or not redis_params or not callback or not command then + return false,nil,nil + end + + local addr + local rspamd_redis = require "rspamd_redis" + + if key then + if is_write then + addr = redis_params['write_servers']:get_upstream_by_hash(key) + else + addr = redis_params['read_servers']:get_upstream_by_hash(key) + end + else + if is_write then + addr = redis_params['write_servers']:get_upstream_master_slave(key) + else + addr = redis_params['read_servers']:get_upstream_round_robin(key) + end + end + + if not addr then + logger.errx(cfg, 'cannot select server to make redis request') + end + + local options = { + ev_base = ev_base, + config = cfg, + callback = callback, + host = addr:get_addr(), + timeout = redis_params['timeout'], + cmd = command, + args = args + } + + if redis_params['password'] then + options['password'] = redis_params['password'] + end + + if redis_params['db'] then + options['dbname'] = redis_params['db'] + end + + local ret,conn = rspamd_redis.make_request(options) + if not ret then + logger.errx('cannot execute redis request') + end + return ret,conn,addr +end + +exports.rspamd_redis_make_request_taskless = redis_make_request_taskless +exports.redis_make_request_taskless = redis_make_request_taskless + +return exports |