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