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