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