diff options
Diffstat (limited to 'apps/files/lib/BackgroundJob')
-rw-r--r-- | apps/files/lib/BackgroundJob/CleanupFileLocks.php | 57 | ||||
-rw-r--r-- | apps/files/lib/BackgroundJob/DeleteOrphanedItems.php | 153 | ||||
-rw-r--r-- | apps/files/lib/BackgroundJob/ScanFiles.php | 114 |
3 files changed, 324 insertions, 0 deletions
diff --git a/apps/files/lib/BackgroundJob/CleanupFileLocks.php b/apps/files/lib/BackgroundJob/CleanupFileLocks.php new file mode 100644 index 00000000000..b5cf8e94551 --- /dev/null +++ b/apps/files/lib/BackgroundJob/CleanupFileLocks.php @@ -0,0 +1,57 @@ +<?php +/** + * @author Morris Jobke <hey@morrisjobke.de> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OCA\Files\BackgroundJob; + +use OC\BackgroundJob\TimedJob; +use OC\Lock\DBLockingProvider; + +/** + * Clean up all file locks that are expired for the DB file locking provider + */ +class CleanupFileLocks extends TimedJob { + + /** + * Default interval in minutes + * + * @var int $defaultIntervalMin + **/ + protected $defaultIntervalMin = 5; + + /** + * sets the correct interval for this timed job + */ + public function __construct() { + $this->interval = $this->defaultIntervalMin * 60; + } + + /** + * Makes the background job do its work + * + * @param array $argument unused argument + */ + public function run($argument) { + $lockingProvider = \OC::$server->getLockingProvider(); + if($lockingProvider instanceof DBLockingProvider) { + $lockingProvider->cleanExpiredLocks(); + } + } +} diff --git a/apps/files/lib/BackgroundJob/DeleteOrphanedItems.php b/apps/files/lib/BackgroundJob/DeleteOrphanedItems.php new file mode 100644 index 00000000000..1eef9c24e0c --- /dev/null +++ b/apps/files/lib/BackgroundJob/DeleteOrphanedItems.php @@ -0,0 +1,153 @@ +<?php +/** + * @author Arthur Schiwon <blizzz@owncloud.com> + * @author Joas Schilling <nickvergessen@owncloud.com> + * @author Vincent Petry <pvince81@owncloud.com> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OCA\Files\BackgroundJob; + +use OC\BackgroundJob\TimedJob; +use OCP\DB\QueryBuilder\IQueryBuilder; + +/** + * Delete all share entries that have no matching entries in the file cache table. + */ +class DeleteOrphanedItems extends TimedJob { + + const CHUNK_SIZE = 200; + + /** @var \OCP\IDBConnection */ + protected $connection; + + /** @var \OCP\ILogger */ + protected $logger; + + /** + * Default interval in minutes + * + * @var int $defaultIntervalMin + **/ + protected $defaultIntervalMin = 60; + + /** + * sets the correct interval for this timed job + */ + public function __construct() { + $this->interval = $this->defaultIntervalMin * 60; + $this->connection = \OC::$server->getDatabaseConnection(); + $this->logger = \OC::$server->getLogger(); + } + + /** + * Makes the background job do its work + * + * @param array $argument unused argument + */ + public function run($argument) { + $this->cleanSystemTags(); + $this->cleanUserTags(); + $this->cleanComments(); + $this->cleanCommentMarkers(); + } + + /** + * Deleting orphaned system tag mappings + * + * @param string $table + * @param string $idCol + * @param string $typeCol + * @return int Number of deleted entries + */ + protected function cleanUp($table, $idCol, $typeCol) { + $deletedEntries = 0; + + $query = $this->connection->getQueryBuilder(); + $query->select('t1.' . $idCol) + ->from($table, 't1') + ->where($query->expr()->eq($typeCol, $query->expr()->literal('files'))) + ->andWhere($query->expr()->isNull('t2.fileid')) + ->leftJoin('t1', 'filecache', 't2', $query->expr()->eq($query->expr()->castColumn('t1.' . $idCol, IQueryBuilder::PARAM_INT), 't2.fileid')) + ->groupBy('t1.' . $idCol) + ->setMaxResults(self::CHUNK_SIZE); + + $deleteQuery = $this->connection->getQueryBuilder(); + $deleteQuery->delete($table) + ->where($deleteQuery->expr()->eq($idCol, $deleteQuery->createParameter('objectid'))); + + $deletedInLastChunk = self::CHUNK_SIZE; + while ($deletedInLastChunk === self::CHUNK_SIZE) { + $result = $query->execute(); + $deletedInLastChunk = 0; + while ($row = $result->fetch()) { + $deletedInLastChunk++; + $deletedEntries += $deleteQuery->setParameter('objectid', (int) $row[$idCol]) + ->execute(); + } + $result->closeCursor(); + } + + return $deletedEntries; + } + + /** + * Deleting orphaned system tag mappings + * + * @return int Number of deleted entries + */ + protected function cleanSystemTags() { + $deletedEntries = $this->cleanUp('systemtag_object_mapping', 'objectid', 'objecttype'); + $this->logger->debug("$deletedEntries orphaned system tag relations deleted", ['app' => 'DeleteOrphanedItems']); + return $deletedEntries; + } + + /** + * Deleting orphaned user tag mappings + * + * @return int Number of deleted entries + */ + protected function cleanUserTags() { + $deletedEntries = $this->cleanUp('vcategory_to_object', 'objid', 'type'); + $this->logger->debug("$deletedEntries orphaned user tag relations deleted", ['app' => 'DeleteOrphanedItems']); + return $deletedEntries; + } + + /** + * Deleting orphaned comments + * + * @return int Number of deleted entries + */ + protected function cleanComments() { + $deletedEntries = $this->cleanUp('comments', 'object_id', 'object_type'); + $this->logger->debug("$deletedEntries orphaned comments deleted", ['app' => 'DeleteOrphanedItems']); + return $deletedEntries; + } + + /** + * Deleting orphaned comment read markers + * + * @return int Number of deleted entries + */ + protected function cleanCommentMarkers() { + $deletedEntries = $this->cleanUp('comments_read_markers', 'object_id', 'object_type'); + $this->logger->debug("$deletedEntries orphaned comment read marks deleted", ['app' => 'DeleteOrphanedItems']); + return $deletedEntries; + } + +} diff --git a/apps/files/lib/BackgroundJob/ScanFiles.php b/apps/files/lib/BackgroundJob/ScanFiles.php new file mode 100644 index 00000000000..dcc180bcfbe --- /dev/null +++ b/apps/files/lib/BackgroundJob/ScanFiles.php @@ -0,0 +1,114 @@ +<?php +/** + * @author Lukas Reschke <lukas@owncloud.com> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OCA\Files\BackgroundJob; + +use OC\Files\Utils\Scanner; +use OCP\IConfig; +use OCP\IDBConnection; +use OCP\ILogger; +use OCP\IUser; +use OCP\IUserManager; + +/** + * Class ScanFiles is a background job used to run the file scanner over the user + * accounts to ensure integrity of the file cache. + * + * @package OCA\Files\BackgroundJob + */ +class ScanFiles extends \OC\BackgroundJob\TimedJob { + /** @var IConfig */ + private $config; + /** @var IUserManager */ + private $userManager; + /** @var IDBConnection */ + private $dbConnection; + /** @var ILogger */ + private $logger; + /** Amount of users that should get scanned per execution */ + const USERS_PER_SESSION = 500; + + /** + * @param IConfig|null $config + * @param IUserManager|null $userManager + * @param IDBConnection|null $dbConnection + * @param ILogger|null $logger + */ + public function __construct(IConfig $config = null, + IUserManager $userManager = null, + IDBConnection $dbConnection = null, + ILogger $logger = null) { + // Run once per 10 minutes + $this->setInterval(60 * 10); + + if (is_null($userManager) || is_null($config)) { + $this->fixDIForJobs(); + } else { + $this->config = $config; + $this->userManager = $userManager; + $this->logger = $logger; + } + } + + protected function fixDIForJobs() { + $this->config = \OC::$server->getConfig(); + $this->userManager = \OC::$server->getUserManager(); + $this->logger = \OC::$server->getLogger(); + } + + /** + * @param IUser $user + */ + protected function runScanner(IUser $user) { + try { + $scanner = new Scanner( + $user->getUID(), + $this->dbConnection, + $this->logger + ); + $scanner->backgroundScan(''); + } catch (\Exception $e) { + $this->logger->logException($e, ['app' => 'files']); + } + \OC_Util::tearDownFS(); + } + + /** + * @param $argument + * @throws \Exception + */ + protected function run($argument) { + $offset = $this->config->getAppValue('files', 'cronjob_scan_files', 0); + $users = $this->userManager->search('', self::USERS_PER_SESSION, $offset); + if (!count($users)) { + // No users found, reset offset and retry + $offset = 0; + $users = $this->userManager->search('', self::USERS_PER_SESSION); + } + + $offset += self::USERS_PER_SESSION; + $this->config->setAppValue('files', 'cronjob_scan_files', $offset); + + foreach ($users as $user) { + $this->runScanner($user); + } + } +} |