diff options
author | Evan Prodromou <evan@prodromou.name> | 2008-07-04 01:04:25 -0400 |
---|---|---|
committer | Evan Prodromou <evan@prodromou.name> | 2008-07-04 01:04:25 -0400 |
commit | 73a0271960a5e7e2bc6e040595d3071d7b689a99 (patch) | |
tree | 569be28a814427c5b0005e4b96ef536ba14ddc60 | |
parent | 784299c25778fccb3292b4f339446f37c11d2bf9 (diff) |
enqueue notices for offline broadcast
darcs-hash:20080704050425-84dde-d0106845c7b16b80be8e0d5ee9ac93a457334df7.gz
-rw-r--r-- | config.php.sample | 4 | ||||
-rw-r--r-- | lib/common.php | 2 | ||||
-rw-r--r-- | lib/util.php | 21 | ||||
-rwxr-xr-x | queuedaemon.php | 102 | ||||
-rwxr-xr-x | xmppdaemon.php | 2 |
5 files changed, 130 insertions, 1 deletions
diff --git a/config.php.sample b/config.php.sample index add56b839..2dbdbb673 100644 --- a/config.php.sample +++ b/config.php.sample @@ -50,3 +50,7 @@ $config['db']['database'] = 'mysql://laconica:microblog@localhost/laconica'; #$config['xmpp']['resource'] = 'uniquename'; #$config['xmpp']['password'] = 'blahblahblah'; +#Do notice broadcasts offline +#If you set this, you must run the queuehandler.php +#as a daemon (with, say, start-stop-daemon) +#$config['queue']['enabled'] = true;
\ No newline at end of file diff --git a/lib/common.php b/lib/common.php index 691d33953..0b5b4ab5c 100644 --- a/lib/common.php +++ b/lib/common.php @@ -51,6 +51,8 @@ $config = array('authority' => 'INVALID TAG', 'date' => 'PUT A DATE HERE', 'prefix' => ''), + 'queue' => + array('enabled' => false), 'license' => array('url' => 'http://creativecommons.org/licenses/by/3.0/', 'title' => 'Creative Commons Attribution 3.0', diff --git a/lib/util.php b/lib/util.php index 4d1abe51a..03d549334 100644 --- a/lib/util.php +++ b/lib/util.php @@ -808,6 +808,25 @@ function common_redirect($url, $code=307) { } function common_broadcast_notice($notice, $remote=false) { + if (common_config('queue', 'enabled')) { + # Do it later! + common_enqueue_notice($notice); + } else { + common_real_broadcast($notice, $remote); + } +} + +# Stick the notice on the queue + +function common_enqueue_notice($notice) { + $qi = new Queue_item(); + $qi->notice_id = $notice->id; + $qi->created = DB_DataObject_Cast::dateTime(); + $result = $qi->insert(); + return $result; +} + +function common_real_broadcast($notice, $remote=false) { // XXX: optionally use a queue system like http://code.google.com/p/microapps/wiki/NQDQ if (!$remote) { # Make sure we have the OMB stuff @@ -939,7 +958,7 @@ function common_ensure_syslog() { function common_log($priority, $msg, $filename=NULL) { common_ensure_syslog(); -# syslog($priority, $msg); + syslog($priority, $msg); } function common_debug($msg, $filename=NULL) { diff --git a/queuedaemon.php b/queuedaemon.php new file mode 100755 index 000000000..9d8a465a6 --- /dev/null +++ b/queuedaemon.php @@ -0,0 +1,102 @@ +#!/usr/bin/env php +<?php +/* + * Laconica - a distributed open-source microblogging tool + * Copyright (C) 2008, Controlez-Vous, 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/>. + */ + +# Abort if called from a web server +if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) { + print "This script must be run from the command line\n"; + exit(); +} + +define('INSTALLDIR', dirname(__FILE__)); +define('LACONICA', true); + +require_once(INSTALLDIR . '/lib/common.php'); + +# Notices should be broadcast in 30 minutes or less + +define('CLAIM_TIMEOUT', 30 * 60); + +function qd_log($priority, $msg) { + common_log($level, 'queuedaemon: '.$msg); +} + +function qd_top_item() { + + $qi = new Queue_item(); + $qi->orderBy('created'); + $qi->whereAdd('claimed is NULL', 'OR'); + $qi->whereAdd('now() - claimed > '.CLAIM_TIMEOUT, 'OR'); + + $qi->limit(1); + + $cnt = $qi->find(TRUE); + + if ($cnt) { + # XXX: potential race condition + # can we force it to only update if claimed is still NULL + # (or old)? + $orig = clone($qi); + $qi->claimed = DB_DataObject_Cast::dateTime(); + $result = $qi->update($orig); + if ($result) { + return $qi; + } + } + $qi = NULL; + return NULL; +} + +function qd_is_remote($notice) { + $user = User::staticGet($notice->profile_id); + return !$user; +} + +$in_a_row = 0; + +do { + qd_log(LOG_INFO, 'checking for queued notices'); + $qi = qd_top_item(); + if ($qi) { + $in_a_row++; + qd_log(LOG_INFO, 'Got queue item #'.$in_a_row.' enqueued '.common_exact_date($qi->created)); + $notice = Notice::staticGet($qi->notice_id); + if ($notice) { + qd_log(LOG_INFO, 'broadcasting notice ID = ' . $notice->id); + # XXX: what to do if broadcast fails? + common_real_broadcast($notice, qd_is_remote($notice)); + qd_log(LOG_INFO, 'finished broadcasting notice ID = ' . $notice->id); + $notice = NULL; + } else { + qd_log(LOG_WARNING, 'queue item for notice that does not exist'); + } + $qi->delete(); + $qi = NULL; + } else { + # In busy times, sleep less + $sleeptime = 30000000/($in_a_row+1); + qd_log(LOG_INFO, 'sleeping ' . $sleeptime . ' microseconds'); + usleep($sleeptime); + $in_a_row = 0; + } + # Clear the DB_DataObject cache so we get fresh data + $GLOBALS['_DB_DATAOBJECT']['CACHE'] = array(); +} while (true); + +?> diff --git a/xmppdaemon.php b/xmppdaemon.php index afe248c8e..fc9d67d2e 100755 --- a/xmppdaemon.php +++ b/xmppdaemon.php @@ -85,6 +85,8 @@ class XMPPDaemon { break; } } + # Flush DB_DataObject cache so we get fresh info + $GLOBALS['_DB_DATAOBJECT']['CACHE'] = array(); } } |