From 66bfb9e76feed2996e83bd4758c282337d99701d Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Wed, 19 Aug 2020 18:16:48 +0000
Subject: [PATCH] Cache clearing rearrangements

---
 src/Worker/ClearCache.php | 35 +++++++----------------------------
 src/Worker/Cron.php       | 39 +++++++++++++++++++++++++++++++++++----
 2 files changed, 42 insertions(+), 32 deletions(-)

diff --git a/src/Worker/ClearCache.php b/src/Worker/ClearCache.php
index d87fd46cce..c19d13194a 100644
--- a/src/Worker/ClearCache.php
+++ b/src/Worker/ClearCache.php
@@ -21,7 +21,6 @@
 
 namespace Friendica\Worker;
 
-use Friendica\Core\Logger;
 use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Model\Photo;
@@ -35,21 +34,12 @@ class ClearCache
 	public static function execute()
 	{
 		$a = DI::app();
-		$last = DI::config()->get('system', 'cache_last_cleared');
-
-		if ($last) {
-			$next = $last + (3600); // Once per hour
-			$clear_cache = ($next <= time());
-		} else {
-			$clear_cache = true;
-		}
-
-		if (!$clear_cache) {
-			return;
-		}
 
 		// clear old cache
 		DI::cache()->clear();
+		if (!DI::config()->get('system', 'optimize_tables')) {
+			DBA::e("OPTIMIZE TABLE `cache`");
+		}
 
 		// clear old item cache files
 		clear_cache();
@@ -76,25 +66,14 @@ class ClearCache
 
 		// Delete the cached OEmbed entries that are older than three month
 		DBA::delete('oembed', ["`created` < NOW() - INTERVAL 3 MONTH"]);
+		if (!DI::config()->get('system', 'optimize_tables')) {
+			DBA::e("OPTIMIZE TABLE `oembed`");
+		}
 
 		// Delete the cached "parse_url" entries that are older than three month
 		DBA::delete('parsed_url', ["`created` < NOW() - INTERVAL 3 MONTH"]);
-
-		if (DI::config()->get('system', 'optimize_tables')) {
-			Logger::info('Optimize start');
-			DBA::e("OPTIMIZE TABLE `auth_codes`");
-			DBA::e("OPTIMIZE TABLE `cache`");
-			DBA::e("OPTIMIZE TABLE `challenge`");
-			DBA::e("OPTIMIZE TABLE `locks`");
-			DBA::e("OPTIMIZE TABLE `oembed`");
+		if (!DI::config()->get('system', 'optimize_tables')) {
 			DBA::e("OPTIMIZE TABLE `parsed_url`");
-			DBA::e("OPTIMIZE TABLE `profile_check`");
-			DBA::e("OPTIMIZE TABLE `session`");
-			DBA::e("OPTIMIZE TABLE `tokens`");
-			DBA::e("OPTIMIZE TABLE `process`");
-			Logger::info('Optimize finished');
 		}
-
-		DI::config()->set('system', 'cache_last_cleared', time());
 	}
 }
diff --git a/src/Worker/Cron.php b/src/Worker/Cron.php
index d7cd7c0546..8f5e55e226 100644
--- a/src/Worker/Cron.php
+++ b/src/Worker/Cron.php
@@ -63,9 +63,6 @@ class Cron
 		// Call possible post update functions
 		Worker::add(PRIORITY_LOW, 'PostUpdate');
 
-		// Clear cache entries
-		Worker::add(PRIORITY_LOW, 'ClearCache');
-
 		// Repair entries in the database
 		Worker::add(PRIORITY_LOW, 'RepairDatabase');
 
@@ -94,6 +91,10 @@ class Cron
 
 			self::checkdeletedContacts();
 
+			if (!DI::config()->get('system', 'optimize_tables')) {
+				self::optimizeTables();
+			}
+	
 			DI::config()->set('system', 'last_expire_day', $d2);
 		}
 
@@ -110,9 +111,20 @@ class Cron
 
 			// Optimizing this table only last seconds
 			if (DI::config()->get('system', 'optimize_tables')) {
-				DBA::e("OPTIMIZE TABLE `workerqueue`");
+				// We are acquiring the two locks from the worker to avoid locking problems
+				if (DI::lock()->acquire(Worker::LOCK_PROCESS, 10)) {
+					if (DI::lock()->acquire(Worker::LOCK_WORKER, 10)) {
+						DBA::e("OPTIMIZE TABLE `workerqueue`");
+						DBA::e("OPTIMIZE TABLE `process`");			
+						DI::lock()->release(Worker::LOCK_WORKER);
+					}
+					DI::lock()->release(Worker::LOCK_PROCESS);
+				}
 			}
 
+			// Clear cache entries
+			Worker::add(PRIORITY_LOW, 'ClearCache');
+
 			DI::config()->set('system', 'last_cron_hourly', time());
 		}
 
@@ -136,6 +148,25 @@ class Cron
 		return;
 	}
 
+	/**
+	 * Optimize tables that are known to grow and shrink all the time
+	 *
+	 * @return void
+	 */
+	private static function optimizeTables()
+	{
+		Logger::info('Optimize start');
+
+		DBA::e("OPTIMIZE TABLE `auth_codes`");
+		DBA::e("OPTIMIZE TABLE `challenge`");
+		DBA::e("OPTIMIZE TABLE `locks`");
+		DBA::e("OPTIMIZE TABLE `profile_check`");
+		DBA::e("OPTIMIZE TABLE `session`");
+		DBA::e("OPTIMIZE TABLE `tokens`");
+
+		DI::lock()->release('optimize_tables');
+	}
+
 	/**
 	 * 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.
-- 
2.39.5