Mercurial > prosody-modules
comparison mod_storage_xmlarchive/mod_storage_xmlarchive.lua @ 4538:591c643d55b2
mod_storage_xmlarchive: Insert micropauses in long-running queries
Allows other processing to be interleaved with long-running queries.
Drops 0.9 support since it requires util.async, but 0.9 really should be
EOL by now.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 10 Apr 2021 01:16:02 +0200 |
parents | a03abb4bb6d7 |
children | b92147edd172 |
comparison
equal
deleted
inserted
replaced
4537:53ee391ca689 | 4538:591c643d55b2 |
---|---|
10 local hmac_sha256 = require"util.hashes".hmac_sha256; | 10 local hmac_sha256 = require"util.hashes".hmac_sha256; |
11 local st = require"util.stanza"; | 11 local st = require"util.stanza"; |
12 local dt = require"util.datetime"; | 12 local dt = require"util.datetime"; |
13 local new_stream = require "util.xmppstream".new; | 13 local new_stream = require "util.xmppstream".new; |
14 local xml = require "util.xml"; | 14 local xml = require "util.xml"; |
15 local async = require "util.async"; | |
15 local empty = {}; | 16 local empty = {}; |
16 | 17 |
17 if not dm.append_raw then | 18 if not dm.append_raw then |
18 module:require"datamanager_append_raw"; | 19 module:require"datamanager_append_raw"; |
19 end | 20 end |
128 }; | 129 }; |
129 local ok, err = dm.list_store(username.."@"..day, self.host, self.store, items); | 130 local ok, err = dm.list_store(username.."@"..day, self.host, self.store, items); |
130 return ok, err; | 131 return ok, err; |
131 end | 132 end |
132 | 133 |
134 local function get_nexttick() | |
135 if async.ready() then | |
136 return function () | |
137 -- slow down | |
138 local wait, done = async.waiter(); | |
139 module:add_timer(0, done); | |
140 wait(); | |
141 end | |
142 else | |
143 -- no async, no-op | |
144 return function () end | |
145 end | |
146 end | |
147 | |
133 function archive:_get_idx(username, id, dates) | 148 function archive:_get_idx(username, id, dates) |
134 module:log("debug", "Looking for item with id %q", id); | 149 module:log("debug", "Looking for item with id %q", id); |
135 dates = dates or self:dates(username) or empty; | 150 dates = dates or self:dates(username) or empty; |
136 local date = id:match("^%d%d%d%d%-%d%d%-%d%d"); | 151 local date = id:match("^%d%d%d%d%-%d%d%-%d%d"); |
152 local tick = get_nexttick(); | |
137 for d = 1, #dates do | 153 for d = 1, #dates do |
138 if not date or date == dates[d] then | 154 if not date or date == dates[d] then |
139 module:log("debug", "Loading index for %s", dates[d]); | 155 module:log("debug", "Loading index for %s", dates[d]); |
140 local items = dm.list_load(username .. "@" .. dates[d], self.host, self.store) or empty; | 156 local items = dm.list_load(username .. "@" .. dates[d], self.host, self.store) or empty; |
141 for i = 1, #items do | 157 for i = 1, #items do |
149 end | 165 end |
150 elseif date and date < dates[d] then | 166 elseif date and date < dates[d] then |
151 module:log("debug", "Skipping remaining dates after %s", date); | 167 module:log("debug", "Skipping remaining dates after %s", date); |
152 return; -- List is assumed to be sorted | 168 return; -- List is assumed to be sorted |
153 end | 169 end |
170 | |
171 -- insert pauses to allow other processing | |
172 if d % 14 == 0 then tick(); end | |
154 end | 173 end |
155 module:log("debug", "Item not found"); | 174 module:log("debug", "Item not found"); |
156 end | 175 end |
157 | 176 |
158 function archive:find(username, query) | 177 function archive:find(username, query) |
259 return nil, err or "seek-failed"; | 278 return nil, err or "seek-failed"; |
260 end | 279 end |
261 return xmlfile:read(length); | 280 return xmlfile:read(length); |
262 end | 281 end |
263 | 282 |
283 local tick = get_nexttick(); | |
284 | |
264 return function () | 285 return function () |
265 if limit and count >= limit then if xmlfile then xmlfile:close() end return; end | 286 if limit and count >= limit then if xmlfile then xmlfile:close() end return; end |
266 for d = start_day, last_day, step do | 287 for d = start_day, last_day, step do |
267 local date = dates[d]; | 288 local date = dates[d]; |
268 if not items then | 289 if not items then |
317 items = nil; | 338 items = nil; |
318 if xmlfile then | 339 if xmlfile then |
319 xmlfile:close(); | 340 xmlfile:close(); |
320 xmlfile = nil; | 341 xmlfile = nil; |
321 end | 342 end |
343 -- If we're running through a lot of day-files then lets allow for other processing between each day | |
344 tick(); | |
322 end | 345 end |
323 end | 346 end |
324 end | 347 end |
325 | 348 |
326 function archive:delete(username, query) | 349 function archive:delete(username, query) |