]> git.mxchange.org Git - friendica.git/blobdiff - src/Worker/Cron.php
Changed worker order
[friendica.git] / src / Worker / Cron.php
index 5bdd22f330b0d707e21853066155ff96915d80fa..a0144e8a2652003224b60d5531a89439beeca2d7 100644 (file)
 
 namespace Friendica\Worker;
 
-use Friendica\Core\Addon;
 use Friendica\Core\Hook;
 use Friendica\Core\Logger;
-use Friendica\Core\Protocol;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\DI;
-use Friendica\Model\Contact;
-use Friendica\Util\DateTimeFormat;
+use Friendica\Model\Tag;
 
 class Cron
 {
@@ -44,257 +41,116 @@ class Cron
                if ($last) {
                        $next = $last + ($poll_interval * 60);
                        if ($next > time()) {
-                               Logger::log('cron intervall not reached');
+                               Logger::notice('cron intervall not reached');
                                return;
                        }
                }
 
-               Logger::log('cron: start');
+               Logger::notice('start');
 
-               // Fork the cron jobs in separate parts to avoid problems when one of them is crashing
-               Hook::fork($a->queue['priority'], "cron");
-
-               // run the process to update server directories in the background
-               Worker::add(PRIORITY_LOW, 'UpdateServerDirectories');
-
-               // run the process to update locally stored global contacts in the background
-               Worker::add(PRIORITY_LOW, 'UpdateGContacts');
-
-               // Expire and remove user entries
-               Worker::add(PRIORITY_MEDIUM, "CronJobs", "expire_and_remove_users");
-
-               // Call possible post update functions
-               Worker::add(PRIORITY_LOW, "CronJobs", "post_update");
-
-               // Clear cache entries
-               Worker::add(PRIORITY_LOW, "CronJobs", "clear_cache");
-
-               // Repair entries in the database
-               Worker::add(PRIORITY_LOW, "CronJobs", "repair_database");
-
-               // once daily run birthday_updates and then expire in background
-               $d1 = DI::config()->get('system', 'last_expire_day');
-               $d2 = intval(DateTimeFormat::utcNow('d'));
-
-               // Daily cron calls
-               if ($d2 != intval($d1)) {
-
-                       Worker::add(PRIORITY_LOW, "CronJobs", "update_contact_birthdays");
-
-                       Worker::add(PRIORITY_LOW, "CronJobs", "update_photo_albums");
+               // Ensure to have a .htaccess file.
+               // this is a precaution for systems that update automatically
+               $basepath = $a->getBasePath();
+               if (!file_exists($basepath . '/.htaccess') && is_writable($basepath)) {
+                       copy($basepath . '/.htaccess-dist', $basepath . '/.htaccess');
+               }
 
-                       // update nodeinfo data
-                       Worker::add(PRIORITY_LOW, "CronJobs", "nodeinfo");
+               if (DI::config()->get('system', 'delete_sleeping_processes')) {
+                       self::deleteSleepingProcesses();
+               }
 
-                       Worker::add(PRIORITY_LOW, 'UpdateGServers');
+               // Fork the cron jobs in separate parts to avoid problems when one of them is crashing
+               Hook::fork(PRIORITY_MEDIUM, 'cron');
 
-                       Worker::add(PRIORITY_LOW, 'UpdateSuggestions');
+               // Poll contacts
+               Worker::add(PRIORITY_MEDIUM, 'PollContacts');
 
-                       Worker::add(PRIORITY_LOW, 'Expire');
+               // Update contact information
+               Worker::add(PRIORITY_LOW, 'UpdateContacts');
 
-                       Worker::add(PRIORITY_MEDIUM, 'DBClean');
+               // Update server information
+               Worker::add(PRIORITY_LOW, 'UpdateGServers');
 
-                       // check upstream version?
-                       Worker::add(PRIORITY_LOW, 'CheckVersion');
+               // run the process to update server directories in the background
+               Worker::add(PRIORITY_LOW, 'UpdateServerDirectories');
 
-                       self::checkdeletedContacts();
+               // Expire and remove user entries
+               Worker::add(PRIORITY_MEDIUM, 'ExpireAndRemoveUsers');
 
-                       DI::config()->set('system', 'last_expire_day', $d2);
-               }
+               // Call possible post update functions
+               Worker::add(PRIORITY_LOW, 'PostUpdate');
 
                // Hourly cron calls
                if (DI::config()->get('system', 'last_cron_hourly', 0) + 3600 < time()) {
 
+                       // Update trending tags cache for the community page
+                       Tag::setLocalTrendingHashtags(24, 20);
+                       Tag::setGlobalTrendingHashtags(24, 20);
+
                        // Search for new contacts in the directory
                        if (DI::config()->get('system', 'synchronize_directory')) {
                                Worker::add(PRIORITY_LOW, 'PullDirectory');
                        }
 
-                       // Delete all done workerqueue entries
-                       DBA::delete('workerqueue', ['`done` AND `executed` < UTC_TIMESTAMP() - INTERVAL 1 HOUR']);
+                       // Delete all done workerqueue entries                  
+                       Worker::add(PRIORITY_LOW, 'CleanWorkerQueue');
 
-                       // Optimizing this table only last seconds
-                       if (DI::config()->get('system', 'optimize_workerqueue', false)) {
-                               DBA::e("OPTIMIZE TABLE `workerqueue`");
-                       }
+                       // Clear cache entries
+                       Worker::add(PRIORITY_LOW, 'ClearCache');
 
                        DI::config()->set('system', 'last_cron_hourly', time());
                }
 
-               // Ensure to have a .htaccess file.
-               // this is a precaution for systems that update automatically
-               $basepath = $a->getBasePath();
-               if (!file_exists($basepath . '/.htaccess') && is_writable($basepath)) {
-                       copy($basepath . '/.htaccess-dist', $basepath . '/.htaccess');
-               }
+               // Daily maintenance cron calls
+               if (Worker::isInMaintenanceWindow(true)) {
 
-               // Poll contacts
-               self::pollContacts();
+                       Worker::add(PRIORITY_LOW, 'UpdateContactBirthdays');
 
-               // Update contact information
-               self::updatePublicContacts();
+                       Worker::add(PRIORITY_LOW, 'UpdatePhotoAlbums');
 
-               Logger::log('cron: end');
+                       Worker::add(PRIORITY_LOW, 'ExpirePosts');
 
-               DI::config()->set('system', 'last_cron', time());
+                       Worker::add(PRIORITY_LOW, 'ExpireConversations');
 
-               return;
-       }
+                       Worker::add(PRIORITY_LOW, 'RemoveUnusedContacts');
 
-       /**
-        * Checks for contacts that are about to be deleted and ensures that they are removed.
-        * This should be done automatically in the "remove" function. This here is a cleanup job.
-        */
-       private static function checkdeletedContacts()
-       {
-               $contacts = DBA::select('contact', ['id'], ['deleted' => true]);
-               while ($contact = DBA::fetch($contacts)) {
-                       Worker::add(PRIORITY_MEDIUM, 'RemoveContact', $contact['id']);
-               }
-               DBA::close($contacts);
-       }
+                       Worker::add(PRIORITY_LOW, 'RemoveUnusedAvatars');
 
-       /**
-        * Update public contacts
-        *
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        */
-       private static function updatePublicContacts() {
-               $count = 0;
-               $last_updated = DateTimeFormat::utc('now - 1 week');
-               $condition = ["`network` IN (?, ?, ?, ?) AND `uid` = ? AND NOT `self` AND `last-update` < ?",
-                       Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, 0, $last_updated];
-
-               $oldest_date = '';
-               $oldest_id = '';
-               $contacts = DBA::select('contact', ['id', 'last-update'], $condition, ['limit' => 100, 'order' => ['last-update']]);
-               while ($contact = DBA::fetch($contacts)) {
-                       if (empty($oldest_id)) {
-                               $oldest_id = $contact['id'];
-                               $oldest_date = $contact['last-update'];
+                       // check upstream version?
+                       Worker::add(PRIORITY_LOW, 'CheckVersion');
+
+                       Worker::add(PRIORITY_LOW, 'CheckDeletedContacts');
+
+                       if (DI::config()->get('system', 'optimize_tables')) {
+                               Worker::add(PRIORITY_LOW, 'OptimizeTables');
                        }
-                       Worker::add(PRIORITY_LOW, "UpdateContact", $contact['id'], 'force');
-                       ++$count;
+       
+                       DI::config()->set('system', 'last_cron_daily', time());
                }
-               Logger::info('Initiated update for public contacts', ['interval' => $count, 'id' => $oldest_id, 'oldest' => $oldest_date]);
-               DBA::close($contacts);
+
+               Logger::notice('end');
+
+               DI::config()->set('system', 'last_cron', time());
        }
 
        /**
-        * Poll contacts for unreceived messages
+        * Kill sleeping database processes
         *
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        * @return void
         */
-       private static function pollContacts() {
-               $min_poll_interval = DI::config()->get('system', 'min_poll_interval', 1);
-
-               Addon::reload();
-
-               $sql = "SELECT `contact`.`id`, `contact`.`nick`, `contact`.`name`, `contact`.`network`, `contact`.`archive`,
-                                       `contact`.`last-update`, `contact`.`priority`, `contact`.`rel`, `contact`.`subhub`
-                               FROM `user`
-                               STRAIGHT_JOIN `contact`
-                               ON `contact`.`uid` = `user`.`uid` AND `contact`.`poll` != ''
-                                       AND `contact`.`network` IN (?, ?, ?, ?, ?)
-                                       AND NOT `contact`.`self` AND NOT `contact`.`blocked`
-                                       AND `contact`.`rel` != ?
-                               WHERE NOT `user`.`account_expired` AND NOT `user`.`account_removed`";
-
-               $parameters = [Protocol::DFRN, Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::FEED, Protocol::MAIL, Contact::FOLLOWER];
-
-               // Only poll from those with suitable relationships,
-               // and which have a polling address and ignore Diaspora since
-               // we are unable to match those posts with a Diaspora GUID and prevent duplicates.
-               $abandon_days = intval(DI::config()->get('system', 'account_abandon_days'));
-               if ($abandon_days < 1) {
-                       $abandon_days = 0;
-               }
-
-               if (!empty($abandon_days)) {
-                       $sql .= " AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL ? DAY";
-                       $parameters[] = $abandon_days;
-               }
-
-               $contacts = DBA::p($sql, $parameters);
-
-               if (!DBA::isResult($contacts)) {
-                       return;
-               }
-
-               while ($contact = DBA::fetch($contacts)) {
-                       // Friendica and OStatus are checked once a day
-                       if (in_array($contact['network'], [Protocol::DFRN, Protocol::OSTATUS])) {
-                               $contact['priority'] = 3;
-                       }
-
-                       // ActivityPub is checked once a week
-                       if ($contact['network'] == Protocol::ACTIVITYPUB) {
-                               $contact['priority'] = 4;
-                       }
-
-                       // Check archived contacts once a month
-                       if ($contact['archive']) {
-                               $contact['priority'] = 5;
-                       }
-
-                       if ($contact['priority'] >= 0) {
-                               $update = false;
-
-                               $t = $contact['last-update'];
-
-                               /*
-                                * Based on $contact['priority'], should we poll this site now? Or later?
-                                */
-                               switch ($contact['priority']) {
-                                       case 5:
-                                               if (DateTimeFormat::utcNow() > DateTimeFormat::utc($t . " + 1 month")) {
-                                                       $update = true;
-                                               }
-                                               break;
-                                       case 4:
-                                               if (DateTimeFormat::utcNow() > DateTimeFormat::utc($t . " + 1 week")) {
-                                                       $update = true;
-                                               }
-                                               break;
-                                       case 3:
-                                               if (DateTimeFormat::utcNow() > DateTimeFormat::utc($t . " + 1 day")) {
-                                                       $update = true;
-                                               }
-                                               break;
-                                       case 2:
-                                               if (DateTimeFormat::utcNow() > DateTimeFormat::utc($t . " + 12 hour")) {
-                                                       $update = true;
-                                               }
-                                               break;
-                                       case 1:
-                                               if (DateTimeFormat::utcNow() > DateTimeFormat::utc($t . " + 1 hour")) {
-                                                       $update = true;
-                                               }
-                                               break;
-                                       case 0:
-                                       default:
-                                               if (DateTimeFormat::utcNow() > DateTimeFormat::utc($t . " + " . $min_poll_interval . " minute")) {
-                                                       $update = true;
-                                               }
-                                               break;
-                               }
-                               if (!$update) {
-                                       continue;
-                               }
-                       }
-
-                       if ((($contact['network'] == Protocol::FEED) && ($contact['priority'] <= 3)) || ($contact['network'] == Protocol::MAIL)) {
-                               $priority = PRIORITY_MEDIUM;
-                       } elseif ($contact['archive']) {
-                               $priority = PRIORITY_NEGLIGIBLE;
-                       } else {
-                               $priority = PRIORITY_LOW;
+       private static function deleteSleepingProcesses()
+       {
+               Logger::info('Looking for sleeping processes');
+               
+               $processes = DBA::p("SHOW FULL PROCESSLIST");
+               while ($process = DBA::fetch($processes)) {
+                       if (($process['Command'] != 'Sleep') || ($process['Time'] < 300) || ($process['db'] != DBA::databaseName())) {
+                               continue;
                        }
 
-                       Logger::log("Polling " . $contact["network"] . " " . $contact["id"] . " " . $contact['priority'] . " " . $contact["nick"] . " " . $contact["name"]);
-
-                       Worker::add(['priority' => $priority, 'dont_fork' => true, 'force_priority' => true], 'OnePoll', (int)$contact['id']);
+                       DBA::e("KILL ?", $process['Id']);
+                       Logger::notice('Killed sleeping process', ['id' => $process['Id']]);
                }
-               DBA::close($contacts);
+               DBA::close($processes);
        }
 }