domovoy/app/Services/Jobs/ScanJobRunner.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
}
}