core/moduleapi.lua
changeset 9737 9ab9aabafa80
parent 9690 e52e4e6e7ffb
child 9751 c8240f931a68
equal deleted inserted replaced
9736:51583ea2b4fd 9737: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);