Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 29 additions & 56 deletions lib/Command/PreGenerate.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use OCA\PreviewGenerator\Service\NoMediaService;
use OCA\PreviewGenerator\SizeHelper;
use OCP\AppFramework\Db\TTransactional;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Encryption\IManager;
use OCP\Files\File;
Expand All @@ -26,6 +27,8 @@
use Symfony\Component\Console\Output\OutputInterface;

class PreGenerate extends Command {
use TTransactional;

/* @return array{width: int, height: int, crop: bool} */
protected array $specifications;

Expand Down Expand Up @@ -87,13 +90,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return 1;
}

if ($this->checkAlreadyRunning()) {
$output->writeln('Command is already running.');
return 2;
}

$this->setPID();

// Set timestamp output
$formatter = new TimestampFormatter($this->config, $output->getFormatter());
$output->setFormatter($formatter);
Expand All @@ -105,38 +101,44 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}
$this->startProcessing();

$this->clearPID();

return 0;
}

private function startProcessing(): void {
while (true) {
$qb = $this->connection->getQueryBuilder();
$qb->select('*')
->from('preview_generation')
->orderBy('id')
->setMaxResults(1000);
$cursor = $qb->executeQuery();
$rows = $cursor->fetchAll();
$cursor->closeCursor();

if ($rows === []) {
break;
}
/*
* Get and delete the row so that if preview generation fails for some reason the next
* run can just continue. Wrap in transaction to make sure that one row is handled by
* one process only.
*/
$row = $this->atomic(function () {
$qb = $this->connection->getQueryBuilder();
$qb->select('*')
->from('preview_generation')
->orderBy('id')
->setMaxResults(1);
$result = $qb->executeQuery();
$row = $result->fetch();
$result->closeCursor();

if (!$row) {
return null;
}

foreach ($rows as $row) {
/*
* First delete the row so that if preview generation fails for some reason
* the next run can just continue
*/
$qb = $this->connection->getQueryBuilder();
$qb->delete('preview_generation')
->where($qb->expr()->eq('id', $qb->createNamedParameter($row['id'])));
$qb->executeStatement();

$this->processRow($row);
return $row;
}, $this->connection);


if (!$row) {
break;
}

$this->processRow($row);
}
}

Expand Down Expand Up @@ -198,33 +200,4 @@ private function processFile(File $file): void {
}
}
}

private function setPID(): void {
$this->config->setAppValue($this->appName, 'pid', posix_getpid());
}

private function clearPID(): void {
$this->config->deleteAppValue($this->appName, 'pid');
}

private function getPID(): int {
return (int)$this->config->getAppValue($this->appName, 'pid', -1);
}

private function checkAlreadyRunning(): bool {
$pid = $this->getPID();

// No PID set so just continue
if ($pid === -1) {
return false;
}

// Get the gid of non running processes so continue
if (posix_getpgid($pid) === false) {
return false;
}

// Seems there is already a running process generating previews
return true;
}
}
Loading