aboutsummaryrefslogtreecommitdiffstats
path: root/server/resty/session/storage/dshm.lua
diff options
context:
space:
mode:
Diffstat (limited to 'server/resty/session/storage/dshm.lua')
-rw-r--r--server/resty/session/storage/dshm.lua163
1 files changed, 163 insertions, 0 deletions
diff --git a/server/resty/session/storage/dshm.lua b/server/resty/session/storage/dshm.lua
new file mode 100644
index 0000000..e6d887f
--- /dev/null
+++ b/server/resty/session/storage/dshm.lua
@@ -0,0 +1,163 @@
+local dshm = require "resty.dshm"
+
+local setmetatable = setmetatable
+local tonumber = tonumber
+local concat = table.concat
+local var = ngx.var
+
+local defaults = {
+ region = var.session_dshm_region or "sessions",
+ connect_timeout = tonumber(var.session_dshm_connect_timeout, 10),
+ read_timeout = tonumber(var.session_dshm_read_timeout, 10),
+ send_timeout = tonumber(var.session_dshm_send_timeout, 10),
+ host = var.session_dshm_host or "127.0.0.1",
+ port = tonumber(var.session_dshm_port, 10) or 4321,
+ pool = {
+ name = var.session_dshm_pool_name,
+ size = tonumber(var.session_dshm_pool_size, 10) or 100,
+ timeout = tonumber(var.session_dshm_pool_timeout, 10) or 1000,
+ backlog = tonumber(var.session_dshm_pool_backlog, 10),
+ },
+}
+
+local storage = {}
+
+storage.__index = storage
+
+function storage.new(session)
+ local config = session.dshm or defaults
+ local pool = config.pool or defaults.pool
+
+ local connect_timeout = tonumber(config.connect_timeout, 10) or defaults.connect_timeout
+
+ local store = dshm:new()
+ if store.set_timeouts then
+ local send_timeout = tonumber(config.send_timeout, 10) or defaults.send_timeout
+ local read_timeout = tonumber(config.read_timeout, 10) or defaults.read_timeout
+
+ if connect_timeout then
+ if send_timeout and read_timeout then
+ store:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ else
+ store:set_timeout(connect_timeout)
+ end
+ end
+
+ elseif store.set_timeout and connect_timeout then
+ store:set_timeout(connect_timeout)
+ end
+
+
+ local self = {
+ store = store,
+ encoder = session.encoder,
+ region = config.region or defaults.region,
+ host = config.host or defaults.host,
+ port = tonumber(config.port, 10) or defaults.port,
+ pool_timeout = tonumber(pool.timeout, 10) or defaults.pool.timeout,
+ connect_opts = {
+ pool = pool.name or defaults.pool.name,
+ pool_size = tonumber(pool.size, 10) or defaults.pool.size,
+ backlog = tonumber(pool.backlog, 10) or defaults.pool.backlog,
+ },
+ }
+
+ return setmetatable(self, storage)
+end
+
+function storage:connect()
+ return self.store:connect(self.host, self.port, self.connect_opts)
+end
+
+function storage:set_keepalive()
+ return self.store:set_keepalive(self.pool_timeout)
+end
+
+function storage:key(id)
+ return concat({ self.region, id }, "::")
+end
+
+function storage:set(key, ttl, data)
+ local ok, err = self:connect()
+ if not ok then
+ return nil, err
+ end
+
+ data, err = self.encoder.encode(data)
+
+ if not data then
+ self:set_keepalive()
+ return nil, err
+ end
+
+ ok, err = self.store:set(key, data, ttl)
+
+ self:set_keepalive()
+
+ return ok, err
+end
+
+function storage:get(key)
+ local ok, err = self:connect()
+ if not ok then
+ return nil, err
+ end
+
+ local data
+ data, err = self.store:get(key)
+ if data then
+ data, err = self.encoder.decode(data)
+ end
+
+ self:set_keepalive()
+
+ return data, err
+end
+
+function storage:delete(key)
+ local ok, err = self:connect()
+ if not ok then
+ return nil, err
+ end
+
+ ok, err = self.store:delete(key)
+
+ self:set_keepalive()
+
+ return ok, err
+end
+
+function storage:touch(key, ttl)
+ local ok, err = self:connect()
+ if not ok then
+ return nil, err
+ end
+
+ ok, err = self.store:touch(key, ttl)
+
+ self:set_keepalive()
+
+ return ok, err
+end
+
+function storage:open(id)
+ local key = self:key(id)
+ return self:get(key)
+end
+
+function storage:save(id, ttl, data)
+ local key = self:key(id)
+ return self:set(key, ttl, data)
+end
+
+function storage:destroy(id)
+ local key = self:key(id)
+ return self:delete(key)
+end
+
+function storage:ttl(id, ttl)
+ local key = self:key(id)
+ return self:touch(key, ttl)
+end
+
+return storage