- break OMB profile update pings to a background queue
- add event hooks to profile update pings - send Salmon pings with custom update-profile event to OStatus subscribees and groups (subscribers will see it on your next post) - fix OStatus queues with overlong transport names, should work on DB queues now - Ostatus_profile::notifyActivity() and ::notifyDeferred() now can take XML, Notice, or Activity for convenience
This commit is contained in:
parent
07214f1370
commit
c36bdc1ba5
@ -691,6 +691,9 @@ class ActivityVerb
|
|||||||
const UNFAVORITE = 'http://ostatus.org/schema/1.0/unfavorite';
|
const UNFAVORITE = 'http://ostatus.org/schema/1.0/unfavorite';
|
||||||
const UNFOLLOW = 'http://ostatus.org/schema/1.0/unfollow';
|
const UNFOLLOW = 'http://ostatus.org/schema/1.0/unfollow';
|
||||||
const LEAVE = 'http://ostatus.org/schema/1.0/leave';
|
const LEAVE = 'http://ostatus.org/schema/1.0/leave';
|
||||||
|
|
||||||
|
// For simple profile-update pings; no content to share.
|
||||||
|
const UPDATE_PROFILE = 'http://ostatus.org/schema/1.0/update-profile';
|
||||||
}
|
}
|
||||||
|
|
||||||
class ActivityContext
|
class ActivityContext
|
||||||
|
48
lib/profilequeuehandler.php
Normal file
48
lib/profilequeuehandler.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* StatusNet - the distributed open-source microblogging tool
|
||||||
|
* Copyright (C) 2010, StatusNet, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package QueueHandler
|
||||||
|
* @maintainer Brion Vibber <brion@status.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ProfileQueueHandler extends QueueHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
function transport()
|
||||||
|
{
|
||||||
|
return 'profile';
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle($profile)
|
||||||
|
{
|
||||||
|
if (!($profile instanceof Profile)) {
|
||||||
|
common_log(LOG_ERR, "Got a bogus profile, not broadcasting");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Event::handle('StartBroadcastProfile', array($profile))) {
|
||||||
|
require_once(INSTALLDIR.'/lib/omb.php');
|
||||||
|
omb_broadcast_profile($profile);
|
||||||
|
}
|
||||||
|
Event::handle('EndBroadcastProfile', array($profile));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -262,6 +262,9 @@ abstract class QueueManager extends IoManager
|
|||||||
$this->connect('sms', 'SmsQueueHandler');
|
$this->connect('sms', 'SmsQueueHandler');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Broadcasting profile updates to OMB remote subscribers
|
||||||
|
$this->connect('profile', 'ProfileQueueHandler');
|
||||||
|
|
||||||
// XMPP output handlers...
|
// XMPP output handlers...
|
||||||
if (common_config('xmpp', 'enabled')) {
|
if (common_config('xmpp', 'enabled')) {
|
||||||
// Delivery prep, read by queuedaemon.php:
|
// Delivery prep, read by queuedaemon.php:
|
||||||
|
14
lib/util.php
14
lib/util.php
@ -1119,12 +1119,16 @@ function common_enqueue_notice($notice)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function common_broadcast_profile($profile)
|
/**
|
||||||
|
* Broadcast profile updates to OMB and other remote subscribers.
|
||||||
|
*
|
||||||
|
* Since this may be slow with a lot of subscribers or bad remote sites,
|
||||||
|
* this is run through the background queues if possible.
|
||||||
|
*/
|
||||||
|
function common_broadcast_profile(Profile $profile)
|
||||||
{
|
{
|
||||||
// XXX: optionally use a queue system like http://code.google.com/p/microapps/wiki/NQDQ
|
$qm = QueueManager::get();
|
||||||
require_once(INSTALLDIR.'/lib/omb.php');
|
$qm->enqueue($profile, "profile");
|
||||||
omb_broadcast_profile($profile);
|
|
||||||
// XXX: Other broadcasts...?
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,14 +82,14 @@ class OStatusPlugin extends Plugin
|
|||||||
$qm->connect('ostatus', 'OStatusQueueHandler');
|
$qm->connect('ostatus', 'OStatusQueueHandler');
|
||||||
|
|
||||||
// Outgoing from our internal PuSH hub
|
// Outgoing from our internal PuSH hub
|
||||||
$qm->connect('hubverify', 'HubVerifyQueueHandler');
|
$qm->connect('hubconf', 'HubConfQueueHandler');
|
||||||
$qm->connect('hubout', 'HubOutQueueHandler');
|
$qm->connect('hubout', 'HubOutQueueHandler');
|
||||||
|
|
||||||
// Outgoing Salmon replies (when we don't need a return value)
|
// Outgoing Salmon replies (when we don't need a return value)
|
||||||
$qm->connect('salmonout', 'SalmonOutQueueHandler');
|
$qm->connect('salmon', 'SalmonQueueHandler');
|
||||||
|
|
||||||
// Incoming from a foreign PuSH hub
|
// Incoming from a foreign PuSH hub
|
||||||
$qm->connect('pushinput', 'PushInputQueueHandler');
|
$qm->connect('pushin', 'PushInQueueHandler');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,4 +656,51 @@ class OStatusPlugin extends Plugin
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ping remote profiles with updates to this profile.
|
||||||
|
* Salmon pings are queued for background processing.
|
||||||
|
*/
|
||||||
|
function onEndBroadcastProfile(Profile $profile)
|
||||||
|
{
|
||||||
|
$user = User::staticGet('id', $profile->id);
|
||||||
|
|
||||||
|
// Find foreign accounts I'm subscribed to that support Salmon pings.
|
||||||
|
//
|
||||||
|
// @fixme we could run updates through the PuSH feed too,
|
||||||
|
// in which case we can skip Salmon pings to folks who
|
||||||
|
// are also subscribed to me.
|
||||||
|
$sql = "SELECT * FROM ostatus_profile " .
|
||||||
|
"WHERE profile_id IN " .
|
||||||
|
"(SELECT subscribed FROM subscription WHERE subscriber=%d) " .
|
||||||
|
"OR group_id IN " .
|
||||||
|
"(SELECT group_id FROM group_member WHERE profile_id=%d)";
|
||||||
|
$oprofile = new Ostatus_profile();
|
||||||
|
$oprofile->query(sprintf($sql, $profile->id, $profile->id));
|
||||||
|
|
||||||
|
if ($oprofile->N == 0) {
|
||||||
|
common_log(LOG_DEBUG, "No OStatus remote subscribees for $profile->nickname");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$act = new Activity();
|
||||||
|
|
||||||
|
$act->verb = ActivityVerb::UPDATE_PROFILE;
|
||||||
|
$act->id = TagURI::mint('update-profile:%d:%s',
|
||||||
|
$profile->id,
|
||||||
|
common_date_iso8601(time()));
|
||||||
|
$act->time = time();
|
||||||
|
$act->title = _m("Profile update");
|
||||||
|
$act->content = sprintf(_m("%s has updated their profile page."),
|
||||||
|
$profile->getBestName());
|
||||||
|
|
||||||
|
$act->actor = ActivityObject::fromProfile($profile);
|
||||||
|
$act->object = $act->actor;
|
||||||
|
|
||||||
|
while ($oprofile->fetch()) {
|
||||||
|
$oprofile->notifyDeferred($act);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ class PushCallbackAction extends Action
|
|||||||
'post' => $post,
|
'post' => $post,
|
||||||
'hmac' => $hmac);
|
'hmac' => $hmac);
|
||||||
$qm = QueueManager::get();
|
$qm = QueueManager::get();
|
||||||
$qm->enqueue($data, 'pushinput');
|
$qm->enqueue($data, 'pushin');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -164,7 +164,7 @@ class HubSub extends Memcached_DataObject
|
|||||||
'token' => $token,
|
'token' => $token,
|
||||||
'retries' => $retries);
|
'retries' => $retries);
|
||||||
$qm = QueueManager::get();
|
$qm = QueueManager::get();
|
||||||
$qm->enqueue($data, 'hubverify');
|
$qm->enqueue($data, 'hubconf');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -431,21 +431,57 @@ class Ostatus_profile extends Memcached_DataObject
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function notifyActivity($activity)
|
/**
|
||||||
|
* Send a Salmon notification ping immediately, and confirm that we got
|
||||||
|
* an acceptable response from the remote site.
|
||||||
|
*
|
||||||
|
* @param mixed $entry XML string, Notice, or Activity
|
||||||
|
* @return boolean success
|
||||||
|
*/
|
||||||
|
public function notifyActivity($entry)
|
||||||
{
|
{
|
||||||
if ($this->salmonuri) {
|
if ($this->salmonuri) {
|
||||||
|
$salmon = new Salmon();
|
||||||
$xml = '<?xml version="1.0" encoding="UTF-8" ?' . '>' .
|
return $salmon->post($this->salmonuri, $this->notifyPrepXml($entry));
|
||||||
$activity->asString(true);
|
|
||||||
|
|
||||||
$salmon = new Salmon(); // ?
|
|
||||||
|
|
||||||
return $salmon->post($this->salmonuri, $xml);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a Salmon notification for later. If queues are disabled we'll
|
||||||
|
* send immediately but won't get the return value.
|
||||||
|
*
|
||||||
|
* @param mixed $entry XML string, Notice, or Activity
|
||||||
|
* @return boolean success
|
||||||
|
*/
|
||||||
|
public function notifyDeferred($entry)
|
||||||
|
{
|
||||||
|
if ($this->salmonuri) {
|
||||||
|
$data = array('salmonuri' => $this->salmonuri,
|
||||||
|
'entry' => $this->notifyPrepXml($entry));
|
||||||
|
|
||||||
|
$qm = QueueManager::get();
|
||||||
|
return $qm->enqueue($data, 'salmon');
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function notifyPrepXml($entry)
|
||||||
|
{
|
||||||
|
$preamble = '<?xml version="1.0" encoding="UTF-8" ?' . '>';
|
||||||
|
if (is_string($entry)) {
|
||||||
|
return $entry;
|
||||||
|
} else if ($entry instanceof Activity) {
|
||||||
|
return $preamble . $entry->asString(true);
|
||||||
|
} else if ($entry instanceof Notice) {
|
||||||
|
return $preamble . $entry->asAtomEntry(true, true);
|
||||||
|
} else {
|
||||||
|
throw new ServerException("Invalid type passed to Ostatus_profile::notify; must be XML string or Activity entry");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getBestName()
|
function getBestName()
|
||||||
{
|
{
|
||||||
if ($this->isGroup()) {
|
if ($this->isGroup()) {
|
||||||
|
@ -22,11 +22,11 @@
|
|||||||
* @package Hub
|
* @package Hub
|
||||||
* @author Brion Vibber <brion@status.net>
|
* @author Brion Vibber <brion@status.net>
|
||||||
*/
|
*/
|
||||||
class HubVerifyQueueHandler extends QueueHandler
|
class HubConfQueueHandler extends QueueHandler
|
||||||
{
|
{
|
||||||
function transport()
|
function transport()
|
||||||
{
|
{
|
||||||
return 'hubverify';
|
return 'hubconf';
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle($data)
|
function handle($data)
|
@ -83,23 +83,11 @@ class OStatusQueueHandler extends QueueHandler
|
|||||||
function pingReply($oprofile)
|
function pingReply($oprofile)
|
||||||
{
|
{
|
||||||
if ($this->user) {
|
if ($this->user) {
|
||||||
if (!empty($oprofile->salmonuri)) {
|
// For local posts, send a Salmon ping to the mentioned
|
||||||
// For local posts, send a Salmon ping to the mentioned
|
// remote user or group.
|
||||||
// remote user or group.
|
// @fixme as an optimization we can skip this if the
|
||||||
// @fixme as an optimization we can skip this if the
|
// remote profile is subscribed to the author.
|
||||||
// remote profile is subscribed to the author.
|
$oprofile->notifyDeferred($this->notice);
|
||||||
|
|
||||||
common_log(LOG_INFO, "Prepping to send notice '{$this->notice->uri}' to remote profile '{$oprofile->uri}'.");
|
|
||||||
|
|
||||||
$xml = '<?xml version="1.0" encoding="UTF-8" ?' . '>';
|
|
||||||
$xml .= $this->notice->asAtomEntry(true, true);
|
|
||||||
|
|
||||||
$data = array('salmonuri' => $oprofile->salmonuri,
|
|
||||||
'entry' => $xml);
|
|
||||||
|
|
||||||
$qm = QueueManager::get();
|
|
||||||
$qm->enqueue($data, 'salmonout');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,11 +23,11 @@
|
|||||||
* @author Brion Vibber <brion@status.net>
|
* @author Brion Vibber <brion@status.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PushInputQueueHandler extends QueueHandler
|
class PushInQueueHandler extends QueueHandler
|
||||||
{
|
{
|
||||||
function transport()
|
function transport()
|
||||||
{
|
{
|
||||||
return 'pushinput';
|
return 'pushin';
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle($data)
|
function handle($data)
|
@ -22,11 +22,11 @@
|
|||||||
* @package OStatusPlugin
|
* @package OStatusPlugin
|
||||||
* @author Brion Vibber <brion@status.net>
|
* @author Brion Vibber <brion@status.net>
|
||||||
*/
|
*/
|
||||||
class SalmonOutQueueHandler extends QueueHandler
|
class SalmonQueueHandler extends QueueHandler
|
||||||
{
|
{
|
||||||
function transport()
|
function transport()
|
||||||
{
|
{
|
||||||
return 'salmonout';
|
return 'salmon';
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle($data)
|
function handle($data)
|
Loading…
Reference in New Issue
Block a user