Add BackgroundQueueCleanUpCronjob
authorTim Düsterhus <duesterhus@woltlab.com>
Sun, 14 Jun 2015 16:25:23 +0000 (18:25 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Sun, 21 Jun 2015 12:59:25 +0000 (14:59 +0200)
com.woltlab.wcf/cronjob.xml
wcfsetup/install/files/lib/system/cronjob/BackgroundQueueCleanUpCronjob.class.php [new file with mode: 0644]

index ef8c93d74470d8b6c4f3cd9bfb25494a6fa8ca79..b8bab7a83ed5bc4c642e17d38733b38fd69f936a 100644 (file)
                        <canbedisabled>1</canbedisabled>
                </cronjob>
                
+               <cronjob name="backgroundQueueCleanUp">
+                       <classname><![CDATA[wcf\system\cronjob\BackgroundQueueCleanUpCronjob]]></classname>
+                       <description><![CDATA[Requeues stuck queue items]]></description>
+                       <description language="de"><![CDATA[Start hängen gebliebene Hintergrundaufgaben neu]]></description>
+                       <startminute>*/10</startminute>
+                       <starthour>*</starthour>
+                       <startdom>*</startdom>
+                       <startmonth>*</startmonth>
+                       <startdow>*</startdow>
+                       <canbeedited>1</canbeedited>
+                       <canbedisabled>1</canbedisabled>
+               </cronjob>
+               
                <cronjob name="lastActivityUpdate">
                        <classname><![CDATA[wcf\system\cronjob\LastActivityCronjob]]></classname>
                        <description><![CDATA[Updates last activity timestamp]]></description>
diff --git a/wcfsetup/install/files/lib/system/cronjob/BackgroundQueueCleanUpCronjob.class.php b/wcfsetup/install/files/lib/system/cronjob/BackgroundQueueCleanUpCronjob.class.php
new file mode 100644 (file)
index 0000000..657ff2b
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+namespace wcf\system\cronjob;
+use wcf\data\cronjob\Cronjob;
+use wcf\system\background\BackgroundQueueHandler;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
+use wcf\system\WCF;
+
+/**
+ * Requeues stuck queue items.
+ * 
+ * @author     Tim Duesterhus
+ * @copyright  2001-2015 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage system.cronjob
+ * @category   Community Framework
+ */
+class BackgroundQueueCleanUpCronjob extends AbstractCronjob {
+       /**
+        * @see \wcf\system\cronjob\ICronjob::execute()
+        */
+       public function execute(Cronjob $cronjob) {
+               parent::execute($cronjob);
+               
+               WCF::getDB()->beginTransaction();
+               $commited = false;
+               try {
+                       $sql = "SELECT          jobID, job
+                               FROM            wcf".WCF_N."_background_job
+                               WHERE           status = ?
+                                       AND     time <= ?
+                               ORDER BY        time ASC, jobID ASC
+                               FOR UPDATE";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute([
+                               'processing',
+                               TIME_NOW - 600 // running longer than 10 minutes
+                       ]);
+                       
+                       $jobIDs = [ ];
+                       while ($row = $statement->fetchArray()) {
+                               $jobIDs[] = $row['jobID'];
+                               
+                               try {
+                                       // no shut up operator, exception will be caught
+                                       $job = unserialize($row['job']);
+                                       if ($job) {
+                                               $job->fail();
+                                               
+                                               if ($job->getFailures() <= $job::MAX_FAILURES) {
+                                                       BackgroundQueueHandler::getInstance()->enqueue($job, TIME_NOW + $job->retryAfter());
+                                               }
+                                       }
+                               }
+                               catch (\Exception $e) {
+                                       // job is completely broken: log
+                                       if ($e instanceof LoggedException) $e->getExceptionID();
+                               }
+                       }
+                       
+                       if (empty($jobIDs)) {
+                               WCF::getDB()->commitTransaction();
+                               $commited = true;
+                               return;
+                       }
+                       
+                       // delete jobs
+                       $condition = new PreparedStatementConditionBuilder();
+                       $condition->add('jobID IN (?)', [ $jobIDs ]);
+                       $sql = "DELETE FROM     wcf".WCF_N."_background_job ".$condition;
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute($condition->getParameters());
+                       
+                       WCF::getDB()->commitTransaction();
+                       $commited = true;
+               }
+               finally {
+                       if (!$commited) WCF::getDB()->rollbackTransaction();
+               }
+       }
+}