SynchronousBackgroundJob.php 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace OC\TaskProcessing;
  7. use OCP\AppFramework\Utility\ITimeFactory;
  8. use OCP\BackgroundJob\IJobList;
  9. use OCP\BackgroundJob\QueuedJob;
  10. use OCP\TaskProcessing\Exception\Exception;
  11. use OCP\TaskProcessing\Exception\NotFoundException;
  12. use OCP\TaskProcessing\IManager;
  13. use OCP\TaskProcessing\ISynchronousProvider;
  14. use OCP\TaskProcessing\Task;
  15. use Psr\Log\LoggerInterface;
  16. class SynchronousBackgroundJob extends QueuedJob {
  17. public function __construct(
  18. ITimeFactory $timeFactory,
  19. private readonly IManager $taskProcessingManager,
  20. private readonly IJobList $jobList,
  21. private readonly LoggerInterface $logger,
  22. ) {
  23. parent::__construct($timeFactory);
  24. }
  25. /**
  26. * @inheritDoc
  27. */
  28. protected function run($argument) {
  29. $providers = $this->taskProcessingManager->getProviders();
  30. foreach ($providers as $provider) {
  31. if (!$provider instanceof ISynchronousProvider) {
  32. continue;
  33. }
  34. $taskTypeId = $provider->getTaskTypeId();
  35. // only use this provider if it is the preferred one
  36. $preferredProvider = $this->taskProcessingManager->getPreferredProvider($taskTypeId);
  37. if ($provider->getId() !== $preferredProvider->getId()) {
  38. continue;
  39. }
  40. try {
  41. $task = $this->taskProcessingManager->getNextScheduledTask([$taskTypeId]);
  42. } catch (NotFoundException $e) {
  43. continue;
  44. } catch (Exception $e) {
  45. $this->logger->error('Unknown error while retrieving scheduled TaskProcessing tasks', ['exception' => $e]);
  46. continue;
  47. }
  48. if (!$this->taskProcessingManager->processTask($task, $provider)) {
  49. // Schedule again
  50. $this->jobList->add(self::class, $argument);
  51. }
  52. }
  53. // check if this job needs to be scheduled again:
  54. // if there is at least one preferred synchronous provider that has a scheduled task
  55. $synchronousProviders = array_filter($providers, fn ($provider) =>
  56. $provider instanceof ISynchronousProvider);
  57. $synchronousPreferredProviders = array_filter($synchronousProviders, function ($provider) {
  58. $taskTypeId = $provider->getTaskTypeId();
  59. $preferredProvider = $this->taskProcessingManager->getPreferredProvider($taskTypeId);
  60. return $provider->getId() === $preferredProvider->getId();
  61. });
  62. $taskTypes = array_values(
  63. array_map(
  64. fn ($provider) => $provider->getTaskTypeId(),
  65. $synchronousPreferredProviders
  66. )
  67. );
  68. $taskTypesWithTasks = array_filter($taskTypes, function ($taskType) {
  69. try {
  70. $this->taskProcessingManager->getNextScheduledTask([$taskType]);
  71. return true;
  72. } catch (NotFoundException|Exception $e) {
  73. return false;
  74. }
  75. });
  76. if (count($taskTypesWithTasks) > 0) {
  77. // Schedule again
  78. $this->jobList->add(self::class, $argument);
  79. }
  80. }
  81. }