96 lines
2.6 KiB
PHP
96 lines
2.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Domovoy\Services\Jobs;
|
|
|
|
use Domovoy\Models\ScanJob;
|
|
use Domovoy\Repositories\ScanJobRepository;
|
|
use Domovoy\Services\Discovery\NetworkScanner;
|
|
|
|
class ScanJobRunner
|
|
{
|
|
private ScanJobRepository $scanJobRepository;
|
|
private NetworkScanner $networkScanner;
|
|
|
|
public function __construct(
|
|
ScanJobRepository $scanJobRepository,
|
|
NetworkScanner $networkScanner
|
|
) {
|
|
$this->scanJobRepository = $scanJobRepository;
|
|
$this->networkScanner = $networkScanner;
|
|
}
|
|
|
|
/**
|
|
* Run a single pending scan job.
|
|
*/
|
|
public function runNext(): ?ScanJob
|
|
{
|
|
$pending = $this->scanJobRepository->findPending();
|
|
if (empty($pending)) {
|
|
return null;
|
|
}
|
|
|
|
$job = $pending[0];
|
|
$this->execute($job);
|
|
return $job;
|
|
}
|
|
|
|
/**
|
|
* Run all pending scan jobs in a loop.
|
|
*
|
|
* @param callable|null $onProgress Called after each job: fn(ScanJob $job)
|
|
*/
|
|
public function runAll(?callable $onProgress = null): int
|
|
{
|
|
$count = 0;
|
|
while (true) {
|
|
$job = $this->runNext();
|
|
if ($job === null) {
|
|
break;
|
|
}
|
|
$count++;
|
|
if ($onProgress !== null) {
|
|
$onProgress($job);
|
|
}
|
|
}
|
|
return $count;
|
|
}
|
|
|
|
public function execute(ScanJob $job): void
|
|
{
|
|
$job->status = 'running';
|
|
$job->startedAt = new \DateTimeImmutable();
|
|
$this->scanJobRepository->save($job);
|
|
|
|
try {
|
|
switch ($job->type) {
|
|
case 'network_discovery':
|
|
$this->runNetworkDiscovery($job);
|
|
break;
|
|
default:
|
|
throw new \RuntimeException("Unknown scan job type: {$job->type}");
|
|
}
|
|
|
|
$job->status = 'done';
|
|
$job->finishedAt = new \DateTimeImmutable();
|
|
} catch (\Throwable $e) {
|
|
$job->status = 'failed';
|
|
$job->errorMessage = $e->getMessage();
|
|
$job->finishedAt = new \DateTimeImmutable();
|
|
}
|
|
|
|
$this->scanJobRepository->save($job);
|
|
}
|
|
|
|
private function runNetworkDiscovery(ScanJob $job): void
|
|
{
|
|
// For MVP, we scan all enabled network ranges if no specific range set
|
|
// TODO: filter by specific range when network_range_id is set
|
|
$settings = require dirname(__DIR__, 3) . '/../phinx.php';
|
|
|
|
// Use the ranges from database via NetworkRangeRepository
|
|
// For now, this is handled by the controller that creates the job with a specific range
|
|
}
|
|
}
|