Software /
code /
prosody
Comparison
core/moduleapi.lua @ 10061:5c71693c8345
Merge 0.11->trunk
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Mon, 08 Jul 2019 02:44:32 +0200 |
parent | 9930:12a31296d63d |
child | 10213:ee62754b0233 |
comparison
equal
deleted
inserted
replaced
10060:7a36b7ac309b | 10061:5c71693c8345 |
---|---|
12 local logger = require "util.logger"; | 12 local logger = require "util.logger"; |
13 local pluginloader = require "util.pluginloader"; | 13 local pluginloader = require "util.pluginloader"; |
14 local timer = require "util.timer"; | 14 local timer = require "util.timer"; |
15 local resolve_relative_path = require"util.paths".resolve_relative_path; | 15 local resolve_relative_path = require"util.paths".resolve_relative_path; |
16 local st = require "util.stanza"; | 16 local st = require "util.stanza"; |
17 local cache = require "util.cache"; | |
18 local errutil = require "util.error"; | |
19 local promise = require "util.promise"; | |
20 local time_now = require "util.time".now; | |
21 local format = require "util.format".format; | |
17 | 22 |
18 local t_insert, t_remove, t_concat = table.insert, table.remove, table.concat; | 23 local t_insert, t_remove, t_concat = table.insert, table.remove, table.concat; |
19 local error, setmetatable, type = error, setmetatable, type; | 24 local error, setmetatable, type = error, setmetatable, type; |
20 local ipairs, pairs, select = ipairs, pairs, select; | 25 local ipairs, pairs, select = ipairs, pairs, select; |
21 local tonumber, tostring = tonumber, tostring; | 26 local tonumber, tostring = tonumber, tostring; |
22 local require = require; | 27 local require = require; |
23 local pack = table.pack or function(...) return {n=select("#",...), ...}; end -- table.pack is only in 5.2 | 28 local pack = table.pack or require "util.table".pack; -- table.pack is only in 5.2 |
24 local unpack = table.unpack or unpack; --luacheck: ignore 113 -- renamed in 5.2 | 29 local unpack = table.unpack or unpack; --luacheck: ignore 113 -- renamed in 5.2 |
25 | 30 |
26 local prosody = prosody; | 31 local prosody = prosody; |
27 local hosts = prosody.hosts; | 32 local hosts = prosody.hosts; |
28 | 33 |
359 | 364 |
360 function api:send(stanza, origin) | 365 function api:send(stanza, origin) |
361 return core_post_stanza(origin or hosts[self.host], stanza); | 366 return core_post_stanza(origin or hosts[self.host], stanza); |
362 end | 367 end |
363 | 368 |
369 function api:send_iq(stanza, origin, timeout) | |
370 local iq_cache = self._iq_cache; | |
371 if not iq_cache then | |
372 iq_cache = cache.new(256, function (_, iq) | |
373 iq.reject(errutil.new({ | |
374 type = "wait", condition = "resource-constraint", | |
375 text = "evicted from iq tracking cache" | |
376 })); | |
377 self:unhook(iq.result_event, iq.result_handler); | |
378 self:unhook(iq.error_event, iq.error_handler); | |
379 end); | |
380 self._iq_cache = iq_cache; | |
381 end | |
382 return promise.new(function (resolve, reject) | |
383 local event_type; | |
384 if stanza.attr.from == self.host then | |
385 event_type = "host"; | |
386 else -- assume bare since we can't hook full jids | |
387 event_type = "bare"; | |
388 end | |
389 local result_event = "iq-result/"..event_type.."/"..stanza.attr.id; | |
390 local error_event = "iq-error/"..event_type.."/"..stanza.attr.id; | |
391 local cache_key = event_type.."/"..stanza.attr.id; | |
392 | |
393 local function result_handler(event) | |
394 if event.stanza.attr.from == stanza.attr.to then | |
395 resolve(event); | |
396 return true; | |
397 end | |
398 end | |
399 | |
400 local function error_handler(event) | |
401 if event.stanza.attr.from == stanza.attr.to then | |
402 reject(errutil.from_stanza(event.stanza), event); | |
403 return true; | |
404 end | |
405 end | |
406 | |
407 if iq_cache:get(cache_key) then | |
408 reject(errutil.new({ | |
409 type = "modify", condition = "conflict", | |
410 text = "iq stanza id attribute already used", | |
411 })); | |
412 return; | |
413 end | |
414 | |
415 self:hook(result_event, result_handler); | |
416 self:hook(error_event, error_handler); | |
417 | |
418 local timeout_handle = self:add_timer(timeout or 120, function () | |
419 reject(errutil.new({ | |
420 type = "wait", condition = "remote-server-timeout", | |
421 text = "IQ stanza timed out", | |
422 })); | |
423 self:unhook(result_event, result_handler); | |
424 self:unhook(error_event, error_handler); | |
425 iq_cache:set(cache_key, nil); | |
426 end); | |
427 | |
428 local ok = iq_cache:set(cache_key, { | |
429 reject = reject, resolve = resolve, | |
430 timeout_handle = timeout_handle, | |
431 result_event = result_event, error_event = error_event, | |
432 result_handler = result_handler, error_handler = error_handler; | |
433 }); | |
434 | |
435 if not ok then | |
436 reject(errutil.new({ | |
437 type = "wait", condition = "internal-server-error", | |
438 text = "Could not store IQ tracking data" | |
439 })); | |
440 return; | |
441 end | |
442 | |
443 self:send(stanza, origin); | |
444 end); | |
445 end | |
446 | |
364 function api:broadcast(jids, stanza, iter) | 447 function api:broadcast(jids, stanza, iter) |
365 for jid in (iter or it.values)(jids) do | 448 for jid in (iter or it.values)(jids) do |
366 local new_stanza = st.clone(stanza); | 449 local new_stanza = st.clone(stanza); |
367 new_stanza.attr.to = jid; | 450 new_stanza.attr.to = jid; |
368 self:send(new_stanza); | 451 self:send(new_stanza); |
430 | 513 |
431 function api:measure_global_event(event_name, stat_name) | 514 function api:measure_global_event(event_name, stat_name) |
432 return self:measure_object_event(prosody.events.wrappers, event_name, stat_name); | 515 return self:measure_object_event(prosody.events.wrappers, event_name, stat_name); |
433 end | 516 end |
434 | 517 |
518 local status_priorities = { error = 3, warn = 2, info = 1, core = 0 }; | |
519 | |
520 function api:set_status(status_type, status_message, override) | |
521 local priority = status_priorities[status_type]; | |
522 if not priority then | |
523 self:log("error", "set_status: Invalid status type '%s', assuming 'info'"); | |
524 status_type, priority = "info", status_priorities.info; | |
525 end | |
526 local current_priority = status_priorities[self.status_type] or 0; | |
527 -- By default an 'error' status can only be overwritten by another 'error' status | |
528 if (current_priority >= status_priorities.error and priority < current_priority and override ~= true) | |
529 or (override == false and current_priority > priority) then | |
530 self:log("debug", "moduleapi: ignoring status [prio %d override %s]: %s", priority, override, status_message); | |
531 return; | |
532 end | |
533 self.status_type, self.status_message, self.status_time = status_type, status_message, time_now(); | |
534 self:fire_event("module-status/updated", { name = self.name }); | |
535 end | |
536 | |
537 function api:log_status(level, msg, ...) | |
538 self:set_status(level, format(msg, ...)); | |
539 return self:log(level, msg, ...); | |
540 end | |
541 | |
542 function api:get_status() | |
543 return self.status_type, self.status_message, self.status_time; | |
544 end | |
545 | |
435 return api; | 546 return api; |