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) |
