Exception handling in queue handler logic

This commit is contained in:
Mikael Nordfeldth 2016-01-14 02:04:15 +01:00
parent cf7d2f4d0f
commit f699ffeb8a
5 changed files with 81 additions and 41 deletions

View File

@ -89,14 +89,18 @@ class DBQueueManager extends QueueManager
$rep = $this->logrep($item); $rep = $this->logrep($item);
$this->_log(LOG_DEBUG, "Got {$rep} for transport {$qi->transport}"); $this->_log(LOG_DEBUG, "Got {$rep} for transport {$qi->transport}");
$handler = $this->getHandler($qi->transport);
if ($handler) {
try { try {
$handler = $this->getHandler($qi->transport);
$result = $handler->handle($item) $result = $handler->handle($item)
} catch (NoQueueHandlerException $e) {
$this->noHandlerFound($qi, $rep);
return true;
} catch (Exception $e) { } catch (Exception $e) {
$result = false;
$this->_log(LOG_ERR, "[{$qi->transport}:$rep] Exception thrown: {$e->getMessage()}"); $this->_log(LOG_ERR, "[{$qi->transport}:$rep] Exception thrown: {$e->getMessage()}");
$this->_fail($qi);
return true;
} }
if ($result) { if ($result) {
$this->_log(LOG_INFO, "[{$qi->transport}:$rep] Successfully handled item"); $this->_log(LOG_INFO, "[{$qi->transport}:$rep] Successfully handled item");
$this->_done($qi); $this->_done($qi);
@ -104,9 +108,6 @@ class DBQueueManager extends QueueManager
$this->_log(LOG_INFO, "[{$qi->transport}:$rep] Failed to handle item"); $this->_log(LOG_INFO, "[{$qi->transport}:$rep] Failed to handle item");
$this->_fail($qi); $this->_fail($qi);
} }
} else {
$this->noHandlerFound($qi, $rep);
}
return true; return true;
} }

View File

@ -0,0 +1,41 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Class for an exception when there is no queuehandler for this transport type
*
* PHP version 5
*
* LICENCE: 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/>.
*
* @category Exception
* @package GNUsocial
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2016 Free Software Foundation, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
class NoQueueHandlerException extends ServerException
{
public $transport; // The object with query that gave no results
public function __construct($transport)
{
$this->transport = $transport;
parent::__construct(sprintf(_('No queue handler found for transport %s.'), _ve($this->transport)));
}
}

View File

@ -509,15 +509,13 @@ class StompQueueManager extends QueueManager
$frame->headers['created'] . " in queue $queue from $host"; $frame->headers['created'] . " in queue $queue from $host";
$this->_log(LOG_DEBUG, "Dequeued $info"); $this->_log(LOG_DEBUG, "Dequeued $info");
try {
$handler = $this->getHandler($queue); $handler = $this->getHandler($queue);
if (!$handler) { $ok = $handler->handle($item);
} catch (NoQueueHandlerException $e) {
$this->_log(LOG_ERR, "Missing handler class; skipping $info"); $this->_log(LOG_ERR, "Missing handler class; skipping $info");
$this->stats('badhandler', $queue); $this->stats('badhandler', $queue);
return false; return false;
}
try {
$ok = $handler->handle($item);
} catch (Exception $e) { } catch (Exception $e) {
$this->_log(LOG_ERR, "Exception on queue $queue: " . $e->getMessage()); $this->_log(LOG_ERR, "Exception on queue $queue: " . $e->getMessage());
$ok = false; $ok = false;

View File

@ -38,19 +38,17 @@ class UnQueueManager extends QueueManager
* that can be processed quickly and don't need polling or long-running * that can be processed quickly and don't need polling or long-running
* connections to another server such as XMPP. * connections to another server such as XMPP.
* *
* @param Notice $object * @param Notice $object this specific manager just handles Notice objects anyway
* @param string $queue * @param string $queue
*/ */
function enqueue($object, $queue) function enqueue($object, $transport)
{ {
$notice = $object; try {
$handler = $this->getHandler($transport);
$handler = $this->getHandler($queue); $handler->handle($object);
if ($handler) { } catch (NoQueueHandlerException $e) {
$handler->handle($notice); if (Event::handle('UnqueueHandleNotice', array(&$object, $transport))) {
} else { throw new ServerException("UnQueueManager: Unknown queue transport: $transport");
if (Event::handle('UnqueueHandleNotice', array(&$notice, $queue))) {
throw new ServerException("UnQueueManager: Unknown queue: $queue");
} }
} }
} }

View File

@ -38,19 +38,21 @@ $queue = trim($args[0]);
$noticeId = intval($args[1]); $noticeId = intval($args[1]);
$qm = QueueManager::get(); $qm = QueueManager::get();
try {
$handler = $qm->getHandler($queue); $handler = $qm->getHandler($queue);
if (!$handler) { $notice = Notice::getByID($noticeId);
$result = $handler->handle($notice);
} catch (NoQueueHandlerException $e) {
print "No handler for queue '$queue'.\n"; print "No handler for queue '$queue'.\n";
exit(1); exit(1);
} } catch (NoResultException $e) {
print "{$e->getMessage()}\n";
$notice = Notice::getKV('id', $noticeId); exit(1);
if (empty($notice)) { } catch (Exception $e) {
print "Invalid notice id $noticeId\n"; print "Exception thrown while handling: {$e->getMessage()}\n";
exit(1); exit(1);
} }
if (!$result) {
if (!$handler->handle($notice)) {
print "Failed to handle notice id $noticeId on queue '$queue'.\n"; print "Failed to handle notice id $noticeId on queue '$queue'.\n";
exit(1); exit(1);
} }