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)