mirror of
https://github.com/nextcloud/server.git
synced 2025-03-16 01:05:24 +00:00
fix(caldav): automatically delete outdated scheduling objects
Signed-off-by: Anna Larch <anna@nextcloud.com>
This commit is contained in:
parent
806e390d14
commit
ec94f5499c
12 changed files with 176 additions and 0 deletions
apps
dav
composer/composer
lib
BackgroundJob
CalDAV
Migration
settings
composer/composer
lib
core
lib/private
|
@ -16,6 +16,7 @@ return array(
|
|||
'OCA\\DAV\\BackgroundJob\\CalendarRetentionJob' => $baseDir . '/../lib/BackgroundJob/CalendarRetentionJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\CleanupDirectLinksJob' => $baseDir . '/../lib/BackgroundJob/CleanupDirectLinksJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\CleanupInvitationTokenJob' => $baseDir . '/../lib/BackgroundJob/CleanupInvitationTokenJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\DeleteOutdatedSchedulingObjects' => $baseDir . '/../lib/BackgroundJob/DeleteOutdatedSchedulingObjects.php',
|
||||
'OCA\\DAV\\BackgroundJob\\EventReminderJob' => $baseDir . '/../lib/BackgroundJob/EventReminderJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\GenerateBirthdayCalendarBackgroundJob' => $baseDir . '/../lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\OutOfOfficeEventDispatcherJob' => $baseDir . '/../lib/BackgroundJob/OutOfOfficeEventDispatcherJob.php',
|
||||
|
@ -288,6 +289,7 @@ return array(
|
|||
'OCA\\DAV\\Migration\\BuildSocialSearchIndexBackgroundJob' => $baseDir . '/../lib/Migration/BuildSocialSearchIndexBackgroundJob.php',
|
||||
'OCA\\DAV\\Migration\\CalDAVRemoveEmptyValue' => $baseDir . '/../lib/Migration/CalDAVRemoveEmptyValue.php',
|
||||
'OCA\\DAV\\Migration\\ChunkCleanup' => $baseDir . '/../lib/Migration/ChunkCleanup.php',
|
||||
'OCA\\DAV\\Migration\\DeleteSchedulingObjects' => $baseDir . '/../lib/Migration/DeleteSchedulingObjects.php',
|
||||
'OCA\\DAV\\Migration\\FixBirthdayCalendarComponent' => $baseDir . '/../lib/Migration/FixBirthdayCalendarComponent.php',
|
||||
'OCA\\DAV\\Migration\\RefreshWebcalJobRegistrar' => $baseDir . '/../lib/Migration/RefreshWebcalJobRegistrar.php',
|
||||
'OCA\\DAV\\Migration\\RegenerateBirthdayCalendars' => $baseDir . '/../lib/Migration/RegenerateBirthdayCalendars.php',
|
||||
|
|
|
@ -31,6 +31,7 @@ class ComposerStaticInitDAV
|
|||
'OCA\\DAV\\BackgroundJob\\CalendarRetentionJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/CalendarRetentionJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\CleanupDirectLinksJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupDirectLinksJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\CleanupInvitationTokenJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupInvitationTokenJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\DeleteOutdatedSchedulingObjects' => __DIR__ . '/..' . '/../lib/BackgroundJob/DeleteOutdatedSchedulingObjects.php',
|
||||
'OCA\\DAV\\BackgroundJob\\EventReminderJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/EventReminderJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\GenerateBirthdayCalendarBackgroundJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\OutOfOfficeEventDispatcherJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/OutOfOfficeEventDispatcherJob.php',
|
||||
|
@ -303,6 +304,7 @@ class ComposerStaticInitDAV
|
|||
'OCA\\DAV\\Migration\\BuildSocialSearchIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/Migration/BuildSocialSearchIndexBackgroundJob.php',
|
||||
'OCA\\DAV\\Migration\\CalDAVRemoveEmptyValue' => __DIR__ . '/..' . '/../lib/Migration/CalDAVRemoveEmptyValue.php',
|
||||
'OCA\\DAV\\Migration\\ChunkCleanup' => __DIR__ . '/..' . '/../lib/Migration/ChunkCleanup.php',
|
||||
'OCA\\DAV\\Migration\\DeleteSchedulingObjects' => __DIR__ . '/..' . '/../lib/Migration/DeleteSchedulingObjects.php',
|
||||
'OCA\\DAV\\Migration\\FixBirthdayCalendarComponent' => __DIR__ . '/..' . '/../lib/Migration/FixBirthdayCalendarComponent.php',
|
||||
'OCA\\DAV\\Migration\\RefreshWebcalJobRegistrar' => __DIR__ . '/..' . '/../lib/Migration/RefreshWebcalJobRegistrar.php',
|
||||
'OCA\\DAV\\Migration\\RegenerateBirthdayCalendars' => __DIR__ . '/..' . '/../lib/Migration/RegenerateBirthdayCalendars.php',
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCA\DAV\BackgroundJob;
|
||||
|
||||
use OCA\DAV\CalDAV\CalDavBackend;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class DeleteOutdatedSchedulingObjects extends TimedJob {
|
||||
public function __construct(
|
||||
private CalDavBackend $calDavBackend,
|
||||
private LoggerInterface $logger,
|
||||
ITimeFactory $timeFactory,
|
||||
) {
|
||||
parent::__construct($timeFactory);
|
||||
$this->setInterval(23 * 60 * 60);
|
||||
$this->setTimeSensitivity(self::TIME_INSENSITIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $argument
|
||||
*/
|
||||
protected function run($argument): void {
|
||||
$time = $this->time->getTime() - (60 * 60);
|
||||
$this->calDavBackend->deleteOutdatedSchedulingObjects($time, 50000);
|
||||
$this->logger->info("Removed outdated scheduling objects");
|
||||
}
|
||||
}
|
|
@ -2738,6 +2738,44 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
->executeStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all scheduling objects last modified before $modifiedBefore from the inbox collection.
|
||||
*
|
||||
* @param int $modifiedBefore
|
||||
* @param int $limit
|
||||
* @return void
|
||||
*/
|
||||
public function deleteOutdatedSchedulingObjects(int $modifiedBefore, int $limit): void {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->select('id')
|
||||
->from('schedulingobjects')
|
||||
->where($query->expr()->lt('lastmodified', $query->createNamedParameter($modifiedBefore)))
|
||||
->setMaxResults($limit);
|
||||
$result = $query->executeQuery();
|
||||
$count = $result->rowCount();
|
||||
if($count === 0) {
|
||||
return;
|
||||
}
|
||||
$ids = array_map(static function (array $id) {
|
||||
return (int)$id[0];
|
||||
}, $result->fetchAll(\PDO::FETCH_NUM));
|
||||
$result->closeCursor();
|
||||
|
||||
$numDeleted = 0;
|
||||
$deleteQuery = $this->db->getQueryBuilder();
|
||||
$deleteQuery->delete('schedulingobjects')
|
||||
->where($deleteQuery->expr()->in('id', $deleteQuery->createParameter('ids'), IQueryBuilder::PARAM_INT_ARRAY));
|
||||
foreach(array_chunk($ids, 1000) as $chunk) {
|
||||
$deleteQuery->setParameter('ids', $chunk, IQueryBuilder::PARAM_INT_ARRAY);
|
||||
$numDeleted += $deleteQuery->executeStatement();
|
||||
}
|
||||
|
||||
if($numDeleted === $limit) {
|
||||
$this->logger->info("Deleted $limit scheduling objects, continuing with next batch");
|
||||
$this->deleteOutdatedSchedulingObjects($modifiedBefore, $limit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new scheduling object. This should land in a users' inbox.
|
||||
*
|
||||
|
|
38
apps/dav/lib/Migration/DeleteSchedulingObjects.php
Normal file
38
apps/dav/lib/Migration/DeleteSchedulingObjects.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCA\DAV\Migration;
|
||||
|
||||
use OCA\DAV\BackgroundJob\DeleteOutdatedSchedulingObjects;
|
||||
use OCA\DAV\CalDAV\CalDavBackend;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use OCP\Migration\IOutput;
|
||||
use OCP\Migration\IRepairStep;
|
||||
|
||||
class DeleteSchedulingObjects implements IRepairStep {
|
||||
public function __construct(private IJobList $jobList,
|
||||
private ITimeFactory $time,
|
||||
private CalDavBackend $calDavBackend
|
||||
) {
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return 'Handle outdated scheduling events';
|
||||
}
|
||||
|
||||
public function run(IOutput $output): void {
|
||||
$output->info('Cleaning up old scheduling events');
|
||||
$time = $this->time->getTime() - (60 * 60);
|
||||
$this->calDavBackend->deleteOutdatedSchedulingObjects($time, 50000);
|
||||
if (!$this->jobList->has(DeleteOutdatedSchedulingObjects::class, null)) {
|
||||
$output->info('Adding background job to delete old scheduling objects');
|
||||
$this->jobList->add(DeleteOutdatedSchedulingObjects::class, null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -383,6 +383,7 @@ class Version1004Date20170825134824 extends SimpleMigrationStep {
|
|||
]);
|
||||
$table->setPrimaryKey(['id']);
|
||||
$table->addIndex(['principaluri'], 'schedulobj_principuri_index');
|
||||
$table->addIndex(['lastmodified'], 'schedulobj_lastmodified_idx');
|
||||
}
|
||||
|
||||
if (!$schema->hasTable('cards_properties')) {
|
||||
|
|
|
@ -117,6 +117,7 @@ return array(
|
|||
'OCA\\Settings\\SetupChecks\\PushService' => $baseDir . '/../lib/SetupChecks/PushService.php',
|
||||
'OCA\\Settings\\SetupChecks\\RandomnessSecure' => $baseDir . '/../lib/SetupChecks/RandomnessSecure.php',
|
||||
'OCA\\Settings\\SetupChecks\\ReadOnlyConfig' => $baseDir . '/../lib/SetupChecks/ReadOnlyConfig.php',
|
||||
'OCA\\Settings\\SetupChecks\\SchedulingTableSize' => $baseDir . '/../lib/SetupChecks/SchedulingTableSize.php',
|
||||
'OCA\\Settings\\SetupChecks\\SecurityHeaders' => $baseDir . '/../lib/SetupChecks/SecurityHeaders.php',
|
||||
'OCA\\Settings\\SetupChecks\\SupportedDatabase' => $baseDir . '/../lib/SetupChecks/SupportedDatabase.php',
|
||||
'OCA\\Settings\\SetupChecks\\SystemIs64bit' => $baseDir . '/../lib/SetupChecks/SystemIs64bit.php',
|
||||
|
|
|
@ -132,6 +132,7 @@ class ComposerStaticInitSettings
|
|||
'OCA\\Settings\\SetupChecks\\PushService' => __DIR__ . '/..' . '/../lib/SetupChecks/PushService.php',
|
||||
'OCA\\Settings\\SetupChecks\\RandomnessSecure' => __DIR__ . '/..' . '/../lib/SetupChecks/RandomnessSecure.php',
|
||||
'OCA\\Settings\\SetupChecks\\ReadOnlyConfig' => __DIR__ . '/..' . '/../lib/SetupChecks/ReadOnlyConfig.php',
|
||||
'OCA\\Settings\\SetupChecks\\SchedulingTableSize' => __DIR__ . '/..' . '/../lib/SetupChecks/SchedulingTableSize.php',
|
||||
'OCA\\Settings\\SetupChecks\\SecurityHeaders' => __DIR__ . '/..' . '/../lib/SetupChecks/SecurityHeaders.php',
|
||||
'OCA\\Settings\\SetupChecks\\SupportedDatabase' => __DIR__ . '/..' . '/../lib/SetupChecks/SupportedDatabase.php',
|
||||
'OCA\\Settings\\SetupChecks\\SystemIs64bit' => __DIR__ . '/..' . '/../lib/SetupChecks/SystemIs64bit.php',
|
||||
|
|
|
@ -86,6 +86,7 @@ use OCA\Settings\SetupChecks\PhpOutputBuffering;
|
|||
use OCA\Settings\SetupChecks\PushService;
|
||||
use OCA\Settings\SetupChecks\RandomnessSecure;
|
||||
use OCA\Settings\SetupChecks\ReadOnlyConfig;
|
||||
use OCA\Settings\SetupChecks\SchedulingTableSize;
|
||||
use OCA\Settings\SetupChecks\SecurityHeaders;
|
||||
use OCA\Settings\SetupChecks\SupportedDatabase;
|
||||
use OCA\Settings\SetupChecks\SystemIs64bit;
|
||||
|
@ -216,6 +217,7 @@ class Application extends App implements IBootstrap {
|
|||
$context->registerSetupCheck(RandomnessSecure::class);
|
||||
$context->registerSetupCheck(ReadOnlyConfig::class);
|
||||
$context->registerSetupCheck(SecurityHeaders::class);
|
||||
$context->registerSetupCheck(SchedulingTableSize::class);
|
||||
$context->registerSetupCheck(SupportedDatabase::class);
|
||||
$context->registerSetupCheck(SystemIs64bit::class);
|
||||
$context->registerSetupCheck(TempSpaceAvailable::class);
|
||||
|
|
48
apps/settings/lib/SetupChecks/SchedulingTableSize.php
Normal file
48
apps/settings/lib/SetupChecks/SchedulingTableSize.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCA\Settings\SetupChecks;
|
||||
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IL10N;
|
||||
use OCP\SetupCheck\ISetupCheck;
|
||||
use OCP\SetupCheck\SetupResult;
|
||||
|
||||
class SchedulingTableSize implements ISetupCheck {
|
||||
public function __construct(
|
||||
private IL10N $l10n,
|
||||
private IDBConnection $connection,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return $this->l10n->t('Scheduling objects table size');
|
||||
}
|
||||
|
||||
public function getCategory(): string {
|
||||
return 'database';
|
||||
}
|
||||
|
||||
public function run(): SetupResult {
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$qb->select($qb->func()->count('id'))
|
||||
->from('schedulingobjects');
|
||||
$query = $qb->executeQuery();
|
||||
$count = $query->fetchOne();
|
||||
$query->closeCursor();
|
||||
|
||||
if ($count > 500000) {
|
||||
return SetupResult::warning(
|
||||
$this->l10n->t('You have more than 500 000 rows in the scheduling objects table. Please run the expensive repair jobs via occ maintenance:repair --include-expensive')
|
||||
);
|
||||
}
|
||||
return SetupResult::success(
|
||||
$this->l10n->t('Scheduling objects table size is within acceptable range.')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -191,6 +191,12 @@ class Application extends App {
|
|||
['principaluri']
|
||||
);
|
||||
|
||||
$event->addMissingIndex(
|
||||
'schedulingobjects',
|
||||
'schedulobj_lastmodified_idx',
|
||||
['lastmodified']
|
||||
);
|
||||
|
||||
$event->addMissingIndex(
|
||||
'properties',
|
||||
'properties_path_index',
|
||||
|
|
|
@ -81,6 +81,7 @@ use OC\Repair\RepairDavShares;
|
|||
use OC\Repair\RepairInvalidShares;
|
||||
use OC\Repair\RepairMimeTypes;
|
||||
use OC\Template\JSCombiner;
|
||||
use OCA\DAV\Migration\DeleteSchedulingObjects;
|
||||
use OCP\AppFramework\QueryException;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Collaboration\Resources\IManager;
|
||||
|
@ -224,6 +225,7 @@ class Repair implements IOutput {
|
|||
return [
|
||||
new OldGroupMembershipShares(\OC::$server->getDatabaseConnection(), \OC::$server->getGroupManager()),
|
||||
\OC::$server->get(ValidatePhoneNumber::class),
|
||||
\OC::$server->get(DeleteSchedulingObjects::class),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue