Software /
code /
prosody
Comparison
plugins/mod_http_file_share.lua @ 11348:f076199b4d38
mod_http_file_share: Cache quotas to avoid hitting storage
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 31 Jan 2021 17:56:49 +0100 |
parent | 11347:5b3ad3c7fe47 |
child | 11349:a219001b449d |
comparison
equal
deleted
inserted
replaced
11347:5b3ad3c7fe47 | 11348:f076199b4d38 |
---|---|
58 filesizefmt = { type = "modify"; condition = "bad-request"; text = "File size must be positive integer"; }; | 58 filesizefmt = { type = "modify"; condition = "bad-request"; text = "File size must be positive integer"; }; |
59 quota = { type = "wait"; condition = "resource-constraint"; text = "Daily quota reached"; }; | 59 quota = { type = "wait"; condition = "resource-constraint"; text = "Daily quota reached"; }; |
60 }); | 60 }); |
61 | 61 |
62 local upload_cache = cache.new(1024); | 62 local upload_cache = cache.new(1024); |
63 local quota_cache = cache.new(1024); | |
63 | 64 |
64 -- Convenience wrapper for logging file sizes | 65 -- Convenience wrapper for logging file sizes |
65 local function B(bytes) return hi.format(bytes, "B", "b"); end | 66 local function B(bytes) return hi.format(bytes, "B", "b"); end |
66 | 67 |
67 local function get_filename(slot, create) | 68 local function get_filename(slot, create) |
68 return dm.getpath(slot, module.host, module.name, "bin", create) | 69 return dm.getpath(slot, module.host, module.name, "bin", create) |
69 end | 70 end |
70 | 71 |
71 -- TODO cache | |
72 function get_daily_quota(uploader) | 72 function get_daily_quota(uploader) |
73 local now = os.time(); | 73 local now = os.time(); |
74 local max_age = now - 86400; | 74 local max_age = now - 86400; |
75 local cached = quota_cache:get(uploader); | |
76 if cached and cached.time > max_age then | |
77 return cached.size; | |
78 end | |
75 local iter, err = uploads:find(nil, {with = uploader; start = max_age }); | 79 local iter, err = uploads:find(nil, {with = uploader; start = max_age }); |
76 if not iter then return iter, err; end | 80 if not iter then return iter, err; end |
77 local total_bytes = 0; | 81 local total_bytes = 0; |
78 for _, slot in iter do | 82 local oldest_upload; |
83 for _, slot, when in iter do | |
79 local size = tonumber(slot.attr.size); | 84 local size = tonumber(slot.attr.size); |
80 if size then total_bytes = total_bytes + size; end | 85 if size then total_bytes = total_bytes + size; end |
81 end | 86 if not oldest_upload then oldest_upload = when; end |
87 end | |
88 quota_cache:set(uploader, { time = oldest_upload or now, size = total_bytes }); | |
82 return total_bytes; | 89 return total_bytes; |
83 end | 90 end |
84 | 91 |
85 function may_upload(uploader, filename, filesize, filetype) -- > boolean, error | 92 function may_upload(uploader, filename, filesize, filetype) -- > boolean, error |
86 local uploader_host = jid.host(uploader); | 93 local uploader_host = jid.host(uploader); |
157 local slot, storage_err = errors.coerce(uploads:append(nil, nil, request, os.time(), uploader)) | 164 local slot, storage_err = errors.coerce(uploads:append(nil, nil, request, os.time(), uploader)) |
158 if not slot then | 165 if not slot then |
159 origin.send(st.error_reply(stanza, storage_err)); | 166 origin.send(st.error_reply(stanza, storage_err)); |
160 return true; | 167 return true; |
161 end | 168 end |
169 | |
170 -- Invalidate cache | |
171 quota_cache:set(uploader, nil); | |
162 | 172 |
163 local authz = get_authz(uploader, filename, filesize, filetype, slot); | 173 local authz = get_authz(uploader, filename, filesize, filetype, slot); |
164 local slot_url = get_url(slot, filename); | 174 local slot_url = get_url(slot, filename); |
165 local upload_url = slot_url; | 175 local upload_url = slot_url; |
166 | 176 |