feat(dump): track async dump jobs in a status table
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace AeonDumpManager\Migration;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Shopware\Core\Framework\Migration\MigrationStep;
|
||||
|
||||
class Migration1789413583CreateDumpJobTable extends MigrationStep
|
||||
{
|
||||
public function getCreationTimestamp(): int
|
||||
{
|
||||
return 1789413583;
|
||||
}
|
||||
|
||||
public function update(Connection $connection): void
|
||||
{
|
||||
$connection->executeStatement(<<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `aeon_dump_manager_job` (
|
||||
`id` BINARY(16) NOT NULL,
|
||||
`status` VARCHAR(20) NOT NULL,
|
||||
`percent` SMALLINT UNSIGNED NULL,
|
||||
`filename` VARCHAR(255) NULL,
|
||||
`error_message` TEXT NULL,
|
||||
`created_at` DATETIME(3) NOT NULL,
|
||||
`updated_at` DATETIME(3) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
|
||||
SQL);
|
||||
}
|
||||
|
||||
public function updateDestructive(Connection $connection): void
|
||||
{
|
||||
// nothing destructive to do
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace AeonDumpManager\Service;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Shopware\Core\Framework\Uuid\Uuid;
|
||||
|
||||
/**
|
||||
* Owns the aeon_dump_manager_job table. Shopware core has no generic
|
||||
* async-job-status framework to hook into (confirmed against core's own
|
||||
* Import/Export source) — this mirrors that pattern with a small dedicated table.
|
||||
*/
|
||||
class DumpJobStatusService
|
||||
{
|
||||
public function __construct(private readonly Connection $connection)
|
||||
{
|
||||
}
|
||||
|
||||
public function createPending(): string
|
||||
{
|
||||
$id = Uuid::randomBytes();
|
||||
|
||||
$this->connection->insert('aeon_dump_manager_job', [
|
||||
'id' => $id,
|
||||
'status' => 'pending',
|
||||
'created_at' => (new \DateTimeImmutable())->format('Y-m-d H:i:s.v'),
|
||||
]);
|
||||
|
||||
return Uuid::fromBytesToHex($id);
|
||||
}
|
||||
|
||||
public function markRunning(string $jobId): void
|
||||
{
|
||||
$this->update($jobId, ['status' => 'running']);
|
||||
}
|
||||
|
||||
public function updateProgress(string $jobId, int $percent): void
|
||||
{
|
||||
$this->update($jobId, ['percent' => min(99, max(0, $percent))]);
|
||||
}
|
||||
|
||||
public function markDone(string $jobId, string $filename): void
|
||||
{
|
||||
$this->update($jobId, ['status' => 'done', 'percent' => 100, 'filename' => $filename]);
|
||||
}
|
||||
|
||||
public function markFailed(string $jobId, string $errorMessage): void
|
||||
{
|
||||
$this->update($jobId, ['status' => 'failed', 'error_message' => $errorMessage]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{id: string, status: string, percent: ?int, filename: ?string, errorMessage: ?string}|null
|
||||
*/
|
||||
public function find(string $jobId): ?array
|
||||
{
|
||||
$row = $this->connection->fetchAssociative(
|
||||
'SELECT LOWER(HEX(id)) AS id, status, percent, filename, error_message FROM aeon_dump_manager_job WHERE id = :id',
|
||||
['id' => Uuid::fromHexToBytes($jobId)]
|
||||
);
|
||||
|
||||
if ($row === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $row['id'],
|
||||
'status' => $row['status'],
|
||||
'percent' => $row['percent'] !== null ? (int) $row['percent'] : null,
|
||||
'filename' => $row['filename'],
|
||||
'errorMessage' => $row['error_message'],
|
||||
];
|
||||
}
|
||||
|
||||
public function purgeOlderThan(\DateTimeImmutable $threshold): void
|
||||
{
|
||||
$this->connection->executeStatement(
|
||||
'DELETE FROM aeon_dump_manager_job WHERE created_at < :threshold',
|
||||
['threshold' => $threshold->format('Y-m-d H:i:s.v')]
|
||||
);
|
||||
}
|
||||
|
||||
private function update(string $jobId, array $data): void
|
||||
{
|
||||
$data['updated_at'] = (new \DateTimeImmutable())->format('Y-m-d H:i:s.v');
|
||||
|
||||
$this->connection->update('aeon_dump_manager_job', $data, ['id' => Uuid::fromHexToBytes($jobId)]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user