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