summaryrefslogtreecommitdiff
path: root/lib/jabber.php
diff options
context:
space:
mode:
authorBrion Vibber <brion@pobox.com>2010-01-22 12:52:36 -0800
committerBrion Vibber <brion@pobox.com>2010-01-22 12:52:36 -0800
commitc7507e7e9dafa6d6e054978e720e4fce3abc9929 (patch)
treed756f2a2c7c9b487b6ef0f066a87f3cde40bc65d /lib/jabber.php
parenta3e484a0e898bb94dd45cd7807bea1a931d7c6a9 (diff)
XMPP queued output & initial retooling of DB queue manager to support non-Notice objects.
Queue handlers for XMPP individual & firehose output now send their XML stanzas to another output queue instead of connecting directly to the chat server. This lets us have as many general processing threads as we need, while all actual XMPP input and output go through a single daemon with a single connection open. This avoids problems with multiple connected resources: * multiple windows shown in some chat clients (psi, gajim, kopete) * extra load on server * incoming message delivery forwarding issues Database changes: * queue_item drops 'notice_id' in favor of a 'frame' blob. This is based on Craig Andrews' work branch to generalize queues to take any object, but conservatively leaving out the serialization for now. Table updater (preserves any existing queued items) in db/rc3to09.sql Code changes to watch out for: * Queue handlers should now define a handle() method instead of handle_notice() * QueueDaemon and XmppDaemon now share common i/o (IoMaster) and respawning thread management (RespawningDaemon) infrastructure. * The polling XmppConfirmManager has been dropped, as the message is queued directly when saving IM settings. * Enable $config['queue']['debug_memory'] to output current memory usage at each run through the event loop to watch for memory leaks To do: * Adapt XMPP i/o to component connection mode for multi-site support. * XMPP input can also be broken out to a queue, which would allow the actual notice save etc to be handled by general queue threads. * Make sure there are no problems with simply pushing serialized Notice objects to queues. * Find a way to improve interactive performance of the database-backed queue handler; polling is pretty painful to XMPP. * Possibly redo the way QueueHandlers are injected into a QueueManager. The grouping used to split out the XMPP output queue is a bit awkward. Conflicts: scripts/xmppdaemon.php
Diffstat (limited to 'lib/jabber.php')
-rw-r--r--lib/jabber.php43
1 files changed, 28 insertions, 15 deletions
diff --git a/lib/jabber.php b/lib/jabber.php
index 4cdfa6746..b6b23521b 100644
--- a/lib/jabber.php
+++ b/lib/jabber.php
@@ -86,6 +86,27 @@ class Sharing_XMPP extends XMPPHP_XMPP
}
/**
+ * Build an XMPP proxy connection that'll save outgoing messages
+ * to the 'xmppout' queue to be picked up by xmppdaemon later.
+ */
+function jabber_proxy()
+{
+ $proxy = new Queued_XMPP(common_config('xmpp', 'host') ?
+ common_config('xmpp', 'host') :
+ common_config('xmpp', 'server'),
+ common_config('xmpp', 'port'),
+ common_config('xmpp', 'user'),
+ common_config('xmpp', 'password'),
+ common_config('xmpp', 'resource') . 'daemon',
+ common_config('xmpp', 'server'),
+ common_config('xmpp', 'debug') ?
+ true : false,
+ common_config('xmpp', 'debug') ?
+ XMPPHP_Log::LEVEL_VERBOSE : null);
+ return $proxy;
+}
+
+/**
* Lazy-connect the configured Jabber account to the configured server;
* if already opened, the same connection will be returned.
*
@@ -143,7 +164,7 @@ function jabber_connect($resource=null)
}
/**
- * send a single notice to a given Jabber address
+ * Queue send for a single notice to a given Jabber address
*
* @param string $to JID to send the notice to
* @param Notice $notice notice to send
@@ -153,10 +174,7 @@ function jabber_connect($resource=null)
function jabber_send_notice($to, $notice)
{
- $conn = jabber_connect();
- if (!$conn) {
- return false;
- }
+ $conn = jabber_proxy();
$profile = Profile::staticGet($notice->profile_id);
if (!$profile) {
common_log(LOG_WARNING, 'Refusing to send notice with ' .
@@ -221,10 +239,7 @@ function jabber_format_entry($profile, $notice)
function jabber_send_message($to, $body, $type='chat', $subject=null)
{
- $conn = jabber_connect();
- if (!$conn) {
- return false;
- }
+ $conn = jabber_proxy();
$conn->message($to, $body, $type, $subject);
return true;
}
@@ -319,7 +334,7 @@ function jabber_special_presence($type, $to=null, $show=null, $status=null)
}
/**
- * broadcast a notice to all subscribers and reply recipients
+ * Queue broadcast of a notice to all subscribers and reply recipients
*
* This function will send a notice to all subscribers on the local server
* who have Jabber addresses, and have Jabber notification enabled, and
@@ -354,7 +369,7 @@ function jabber_broadcast_notice($notice)
$sent_to = array();
- $conn = jabber_connect();
+ $conn = jabber_proxy();
$ni = $notice->whoGets();
@@ -389,14 +404,13 @@ function jabber_broadcast_notice($notice)
'Sending notice ' . $notice->id . ' to ' . $user->jabber,
__FILE__);
$conn->message($user->jabber, $msg, 'chat', null, $entry);
- $conn->processTime(0);
}
return true;
}
/**
- * send a notice to all public listeners
+ * Queue send of a notice to all public listeners
*
* For notices that are generated on the local system (by users), we can optionally
* forward them to remote listeners by XMPP.
@@ -429,7 +443,7 @@ function jabber_public_notice($notice)
$msg = jabber_format_notice($profile, $notice);
$entry = jabber_format_entry($profile, $notice);
- $conn = jabber_connect();
+ $conn = jabber_proxy();
foreach ($public as $address) {
common_log(LOG_INFO,
@@ -437,7 +451,6 @@ function jabber_public_notice($notice)
' to public listener ' . $address,
__FILE__);
$conn->message($address, $msg, 'chat', null, $entry);
- $conn->processTime(0);
}
$profile->free();
}