Software / code / prosody
Comparison
core/moduleapi.lua @ 9733:9ab9aabafa80
core.moduleapi: Add a promise-based API for tracking IQ stanzas (fixes #714)
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Fri, 28 Dec 2018 20:51:31 +0100 |
| parent | 9686:e52e4e6e7ffb |
| child | 9747:c8240f931a68 |
comparison
equal
deleted
inserted
replaced
| 9732:51583ea2b4fd | 9733:9ab9aabafa80 |
|---|---|
| 359 | 359 |
| 360 function api:send(stanza, origin) | 360 function api:send(stanza, origin) |
| 361 return core_post_stanza(origin or hosts[self.host], stanza); | 361 return core_post_stanza(origin or hosts[self.host], stanza); |
| 362 end | 362 end |
| 363 | 363 |
| 364 function api:send_iq(stanza, origin, timeout) | |
| 365 local iq_cache = self._iq_cache; | |
| 366 if not iq_cache then | |
| 367 iq_cache = require "util.cache".new(256, function (_, iq) | |
| 368 iq.reject("evicted"); | |
| 369 self:unhook(iq.result_event, iq.result_handler); | |
| 370 self:unhook(iq.error_event, iq.error_handler); | |
| 371 end); | |
| 372 self._iq_cache = iq_cache; | |
| 373 end | |
| 374 return require "util.promise".new(function (resolve, reject) | |
| 375 local event_type; | |
| 376 if stanza.attr.from == self.host then | |
| 377 event_type = "host"; | |
| 378 else -- assume bare since we can't hook full jids | |
| 379 event_type = "bare"; | |
| 380 end | |
| 381 local result_event = "iq-result/"..event_type.."/"..stanza.attr.id; | |
| 382 local error_event = "iq-error/"..event_type.."/"..stanza.attr.id; | |
| 383 local cache_key = event_type.."/"..stanza.attr.id; | |
| 384 | |
| 385 local function result_handler(event) | |
| 386 if event.stanza.attr.from == stanza.attr.to then | |
| 387 resolve(event); | |
| 388 return true; | |
| 389 end | |
| 390 end | |
| 391 | |
| 392 local function error_handler(event) | |
| 393 if event.stanza.attr.from == stanza.attr.to then | |
| 394 reject(event); | |
| 395 return true; | |
| 396 end | |
| 397 end | |
| 398 | |
| 399 if iq_cache:get(cache_key) then | |
| 400 error("choose another iq stanza id attribute") | |
| 401 end | |
| 402 | |
| 403 self:hook(result_event, result_handler); | |
| 404 self:hook(error_event, error_handler); | |
| 405 | |
| 406 local timeout_handle = self:add_timer(timeout or 120, function () | |
| 407 reject("timeout"); | |
| 408 self:unhook(result_event, result_handler); | |
| 409 self:unhook(error_event, error_handler); | |
| 410 iq_cache:set(cache_key, nil); | |
| 411 end); | |
| 412 | |
| 413 local ok = iq_cache:set(cache_key, { | |
| 414 reject = reject, resolve = resolve, | |
| 415 timeout_handle = timeout_handle, | |
| 416 result_event = result_event, error_event = error_event, | |
| 417 result_handler = result_handler, error_handler = error_handler; | |
| 418 }); | |
| 419 | |
| 420 if not ok then | |
| 421 reject("cache insertion failure"); | |
| 422 return; | |
| 423 end | |
| 424 | |
| 425 self:send(stanza, origin); | |
| 426 end); | |
| 427 end | |
| 428 | |
| 364 function api:broadcast(jids, stanza, iter) | 429 function api:broadcast(jids, stanza, iter) |
| 365 for jid in (iter or it.values)(jids) do | 430 for jid in (iter or it.values)(jids) do |
| 366 local new_stanza = st.clone(stanza); | 431 local new_stanza = st.clone(stanza); |
| 367 new_stanza.attr.to = jid; | 432 new_stanza.attr.to = jid; |
| 368 self:send(new_stanza); | 433 self:send(new_stanza); |