| 
									
										
										
										
											2009-06-28 14:38:31 -04:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2019-09-11 14:14:40 +03:00
										 |  |  | // This file is part of GNU social - https://www.gnu.org/software/social
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // GNU social 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.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // GNU social 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 GNU social.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-28 14:38:31 -04:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Simple-minded queue manager for storing items in the database | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @category  QueueManager | 
					
						
							| 
									
										
										
										
											2019-09-11 14:14:40 +03:00
										 |  |  |  * @package   GNUsocial | 
					
						
							| 
									
										
										
										
											2009-08-25 18:19:04 -04:00
										 |  |  |  * @author    Evan Prodromou <evan@status.net> | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |  * @author    Brion Vibber <brion@status.net> | 
					
						
							|  |  |  |  * @copyright 2009-2010 StatusNet, Inc. | 
					
						
							| 
									
										
										
										
											2019-09-11 14:14:40 +03:00
										 |  |  |  * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later | 
					
						
							| 
									
										
										
										
											2009-06-28 14:38:31 -04:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-11 14:14:40 +03:00
										 |  |  | defined('GNUSOCIAL') || die(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-28 14:38:31 -04:00
										 |  |  | class DBQueueManager extends QueueManager | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2010-01-22 12:52:36 -08:00
										 |  |  |      * Saves an object reference into the queue item table. | 
					
						
							| 
									
										
										
										
											2020-08-29 16:09:10 +01:00
										 |  |  |      * @return bool true on success | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |      * @throws ServerException on failure | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function enqueue($object, $queue) | 
					
						
							| 
									
										
										
										
											2009-06-28 14:38:31 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         $qi = new Queue_item(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-11 14:14:40 +03:00
										 |  |  |         $qi->frame     = DB_DataObject_Cast::blob($this->encode($object)); | 
					
						
							| 
									
										
										
										
											2009-06-28 14:38:31 -04:00
										 |  |  |         $qi->transport = $queue; | 
					
						
							| 
									
										
										
										
											2010-01-22 12:52:36 -08:00
										 |  |  |         $qi->created   = common_sql_now(); | 
					
						
							| 
									
										
										
										
											2009-06-28 14:38:31 -04:00
										 |  |  |         $result        = $qi->insert(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-13 18:15:21 +01:00
										 |  |  |         if ($result === false) { | 
					
						
							| 
									
										
										
										
											2009-06-28 14:38:31 -04:00
										 |  |  |             common_log_db_error($qi, 'INSERT', __FILE__); | 
					
						
							|  |  |  |             throw new ServerException('DB error inserting queue item'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |         $this->stats('enqueued', $queue); | 
					
						
							| 
									
										
										
										
											2009-06-28 14:38:31 -04:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2010-01-22 12:52:36 -08:00
										 |  |  |      * Poll every 10 seconds for new events during idle periods. | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |      * We'll look in more often when there's data available. | 
					
						
							| 
									
										
										
										
											2019-08-31 23:53:01 +01:00
										 |  |  |      * Must be greater than 0 for the poll method to be called | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return int seconds | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function pollInterval() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-01-22 12:52:36 -08:00
										 |  |  |         return 10; | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Run a polling cycle during idle processing in the input loop. | 
					
						
							| 
									
										
										
										
											2010-01-22 12:52:36 -08:00
										 |  |  |      * @return boolean true if we should poll again for more data immediately | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-08-31 23:53:01 +01:00
										 |  |  |     public function poll(): bool | 
					
						
							| 
									
										
										
										
											2009-07-04 00:31:28 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-08-31 23:53:01 +01:00
										 |  |  |         $this->_log(LOG_DEBUG, 'Checking for notices...'); | 
					
						
							| 
									
										
										
										
											2015-07-18 01:09:50 +02:00
										 |  |  |         $qi = Queue_item::top($this->activeQueues(), $this->getIgnoredTransports()); | 
					
						
							| 
									
										
										
										
											2015-04-09 12:15:34 +02:00
										 |  |  |         if (!$qi instanceof Queue_item) { | 
					
						
							| 
									
										
										
										
											2013-10-05 13:12:16 +02:00
										 |  |  |             //$this->_log(LOG_DEBUG, 'No notices waiting; idling.');
 | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-25 18:15:34 +02:00
										 |  |  |         try { | 
					
						
							|  |  |  |             $item = $this->decode($qi->frame); | 
					
						
							|  |  |  |         } catch (Exception $e) { | 
					
						
							| 
									
										
										
										
											2016-10-23 12:14:02 +02:00
										 |  |  |             $this->_log(LOG_INFO, "[{$qi->transport}] Discarding: "._ve($e->getMessage())); | 
					
						
							| 
									
										
										
										
											2013-10-25 18:15:34 +02:00
										 |  |  |             $this->_done($qi); | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-01-22 12:52:36 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-25 18:15:34 +02:00
										 |  |  |         $rep = $this->logrep($item); | 
					
						
							| 
									
										
										
										
											2016-10-23 12:14:02 +02:00
										 |  |  |         $this->_log(LOG_DEBUG, 'Got '._ve($rep).' for transport '._ve($qi->transport)); | 
					
						
							| 
									
										
										
										
											2019-08-31 23:53:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-14 02:04:15 +01:00
										 |  |  |         try { | 
					
						
							|  |  |  |             $handler = $this->getHandler($qi->transport); | 
					
						
							| 
									
										
										
										
											2016-01-14 02:05:33 +01:00
										 |  |  |             $result = $handler->handle($item); | 
					
						
							| 
									
										
										
										
											2016-01-14 02:04:15 +01:00
										 |  |  |         } catch (NoQueueHandlerException $e) { | 
					
						
							| 
									
										
										
										
											2015-04-09 12:15:34 +02:00
										 |  |  |             $this->noHandlerFound($qi, $rep); | 
					
						
							| 
									
										
										
										
											2016-01-14 02:04:15 +01:00
										 |  |  |             return true; | 
					
						
							| 
									
										
										
										
											2016-08-16 20:27:41 +02:00
										 |  |  |         } catch (NoResultException $e) { | 
					
						
							| 
									
										
										
										
											2019-08-31 23:53:01 +01:00
										 |  |  |             $this->_log(LOG_ERR, "[{$qi->transport}:$rep] ".get_class($e).' thrown ('. | 
					
						
							|  |  |  |                         _ve($e->getMessage()).'), ignoring queue_item '._ve($qi->getID())); | 
					
						
							| 
									
										
										
										
											2016-08-16 20:27:41 +02:00
										 |  |  |             $result = true; | 
					
						
							| 
									
										
										
										
											2016-01-16 21:05:34 +01:00
										 |  |  |         } catch (AlreadyFulfilledException $e) { | 
					
						
							| 
									
										
										
										
											2019-08-31 23:53:01 +01:00
										 |  |  |             $this->_log(LOG_ERR, "[{$qi->transport}:$rep] ".get_class($e).' thrown ('. | 
					
						
							|  |  |  |                         _ve($e->getMessage()).'), ignoring queue_item '._ve($qi->getID())); | 
					
						
							| 
									
										
										
										
											2016-01-16 21:05:34 +01:00
										 |  |  |             $result = true; | 
					
						
							| 
									
										
										
										
											2016-01-14 02:04:15 +01:00
										 |  |  |         } catch (Exception $e) { | 
					
						
							| 
									
										
										
										
											2019-08-31 23:53:01 +01:00
										 |  |  |             $this->_log(LOG_ERR, "[{$qi->transport}:$rep] Exception (". | 
					
						
							|  |  |  |                         get_class($e).') thrown: '._ve($e->getMessage())); | 
					
						
							| 
									
										
										
										
											2016-01-16 21:05:34 +01:00
										 |  |  |             $result = false; | 
					
						
							| 
									
										
										
										
											2016-01-14 02:04:15 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($result) { | 
					
						
							|  |  |  |             $this->_log(LOG_INFO, "[{$qi->transport}:$rep] Successfully handled item"); | 
					
						
							|  |  |  |             $this->_done($qi); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $this->_log(LOG_INFO, "[{$qi->transport}:$rep] Failed to handle item"); | 
					
						
							|  |  |  |             $this->_fail($qi); | 
					
						
							| 
									
										
										
										
											2009-07-04 00:31:28 -04:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2009-07-04 00:31:28 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 12:15:34 +02:00
										 |  |  |     // What to do if no handler was found. For example, the OpportunisticQM
 | 
					
						
							|  |  |  |     // should avoid deleting items just because it can't reach XMPP queues etc.
 | 
					
						
							| 
									
										
										
										
											2019-09-11 14:14:40 +03:00
										 |  |  |     protected function noHandlerFound(Queue_item $qi, $rep = null) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2015-04-09 12:15:34 +02:00
										 |  |  |         $this->_log(LOG_INFO, "[{$qi->transport}:{$rep}] No handler for queue {$qi->transport}; discarding."); | 
					
						
							|  |  |  |         $this->_done($qi); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Delete our claimed item from the queue after successful processing. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2010-01-22 12:52:36 -08:00
										 |  |  |      * @param QueueItem $qi | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2015-04-09 12:15:34 +02:00
										 |  |  |     protected function _done(Queue_item $qi) | 
					
						
							| 
									
										
										
										
											2009-06-28 14:38:31 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-01-22 12:52:36 -08:00
										 |  |  |         if (empty($qi->claimed)) { | 
					
						
							| 
									
										
										
										
											2015-04-09 12:15:34 +02:00
										 |  |  |             $this->_log(LOG_WARNING, "Reluctantly releasing unclaimed queue item {$qi->id} from {$qi->transport}"); | 
					
						
							| 
									
										
										
										
											2009-06-28 14:38:31 -04:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-01-22 12:52:36 -08:00
										 |  |  |         $qi->delete(); | 
					
						
							| 
									
										
										
										
											2009-06-28 14:38:31 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 12:15:34 +02:00
										 |  |  |         $this->stats('handled', $qi->transport); | 
					
						
							| 
									
										
										
										
											2009-07-01 12:10:25 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Free our claimed queue item for later reprocessing in case of | 
					
						
							|  |  |  |      * temporary failure. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2010-01-22 12:52:36 -08:00
										 |  |  |      * @param QueueItem $qi | 
					
						
							| 
									
										
										
										
											2010-01-12 19:57:15 -08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2015-04-09 12:15:34 +02:00
										 |  |  |     protected function _fail(Queue_item $qi, $releaseOnly=false) | 
					
						
							| 
									
										
										
										
											2009-07-01 12:10:25 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-01-22 12:52:36 -08:00
										 |  |  |         if (empty($qi->claimed)) { | 
					
						
							| 
									
										
										
										
											2015-04-09 12:15:34 +02:00
										 |  |  |             $this->_log(LOG_WARNING, "[{$qi->transport}:item {$qi->id}] Ignoring failure for unclaimed queue item"); | 
					
						
							| 
									
										
										
										
											2009-07-01 12:10:25 -04:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2010-06-26 15:07:32 -04:00
										 |  |  |             $qi->releaseClaim(); | 
					
						
							| 
									
										
										
										
											2009-07-01 12:10:25 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 12:15:34 +02:00
										 |  |  |         if (!$releaseOnly) { | 
					
						
							|  |  |  |             $this->stats('error', $qi->transport); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-06-28 14:38:31 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | } |