ENHANCEMENT: using querybuilder

Signed-off-by: Jeroen De Meerleer <me@jeroened.be>
This commit is contained in:
Jeroen De Meerleer 2022-05-19 15:48:06 +02:00
parent e77086fa52
commit 47c698faf4
Signed by: JeroenED
GPG Key ID: 28CCCB8F62BFADD6
3 changed files with 89 additions and 50 deletions

View File

@ -81,7 +81,8 @@ class JobController extends AbstractController
public function runNowAction(Request $request, ManagerRegistry $doctrine, int $id) { public function runNowAction(Request $request, ManagerRegistry $doctrine, int $id) {
if($request->getMethod() == 'GET') { if($request->getMethod() == 'GET') {
$jobRepo = $doctrine->getRepository(Job::class); $jobRepo = $doctrine->getRepository(Job::class);
return new JsonResponse($jobRepo->runNow($id)); $job = $jobRepo->find($id);
return new JsonResponse($jobRepo->runNow($job));
} }
} }
} }

View File

@ -340,9 +340,7 @@ class JobRepository extends EntityRepository
$manual = $this->getTempVar($job, 'manual'); $manual = $this->getTempVar($job, 'manual');
$this->deleteTempVar($job, 'manual'); $this->deleteTempVar($job, 'manual');
$jobsSql = "UPDATE job SET running = :status WHERE id = :id"; $this->setJobRunning($job, true);
$jobsStmt = $this->getEntityManager()->getConnection()->prepare($jobsSql);
$jobsStmt->executeQuery([':id' => $job->getId(), ':status' => 1]);
if (!empty($job->getData('vars'))) { if (!empty($job->getData('vars'))) {
foreach ($job->getData('vars') as $key => $var) { foreach ($job->getData('vars') as $key => $var) {
@ -374,13 +372,16 @@ class JobRepository extends EntityRepository
* @throws \Doctrine\DBAL\Exception * @throws \Doctrine\DBAL\Exception
*/ */
public function runNow(Job &$job, $console = false) { public function runNow(Job &$job, $console = false) {
$em = $this->getEntityManager();
$this->parseJob($job, true); $this->parseJob($job, true);
$runRepo = $this->getEntityManager()->getRepository(Run::class); $runRepo = $this->getEntityManager()->getRepository(Run::class);
if($console == false && ($runRepo->isSlowJob($job->getId()) || count($job->getRuns()) == 0 || $job->getData('crontype') === 'reboot')) { if($console == false && ($runRepo->isSlowJob($job)) || count($job->getRuns()) == 0 || $job->getData('crontype') === 'reboot') {
$jobsSql = "UPDATE job SET running = :status WHERE id = :id AND running IN (0,1,2)"; if(in_array($job->getRunning(), [0,1,2])) {
$jobsStmt = $this->getEntityManager()->getConnection()->prepare($jobsSql); $job->setRunning(2);
$jobsStmt->executeQuery([':id' => $job->getId(), ':status' => 2]); $em->persist($job);
$em->flush();
}
} else { } else {
$output = $this->runJob($job, true); $output = $this->runJob($job, true);
if(!(isset($output['status']) && $output['status'] == 'deferred')) if(!(isset($output['status']) && $output['status'] == 'deferred'))
@ -477,18 +478,20 @@ class JobRepository extends EntityRepository
* @return void * @return void
* @throws \Doctrine\DBAL\Exception * @throws \Doctrine\DBAL\Exception
*/ */
public function unlockJob(int $id = 0): void public function unlockJob(?Job $job = NULL): void
{ {
$jobsSql = "UPDATE job SET running = :status WHERE running = 1"; $qb = $this->createQueryBuilder('job');
$params = [':status' => 0]; $qry = $qb
->update()
->set('job.running', 0)
->where('job.running = 1');
if($id != 0) { if($job !== NULL) {
$jobsSql .= " AND id = :id"; $qry = $qry
$params[':id'] = $id; ->andWhere('job = :job')
->setParameter(':job', $job);
} }
$jobsStmt = $this->getEntityManager()->getConnection()->prepare($jobsSql); $qry->getQuery()->execute();
$jobsStmt->executeQuery($params);
return;
} }
/** /**

View File

@ -5,6 +5,7 @@ namespace App\Repository;
use App\Entity\Job; use App\Entity\Job;
use App\Entity\Run;
use Doctrine\DBAL\Exception; use Doctrine\DBAL\Exception;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
@ -32,65 +33,99 @@ class RunRepository extends EntityRepository
return $runs->getQuery()->getResult(); return $runs->getQuery()->getResult();
} }
public function addRun(int $jobid, string $exitcode, int $starttime, float $runtime, string $output, array $flags): void public function addRun(Job $job, string $exitcode, int $starttime, float $runtime, string $output, array $flags): void
{ {
// handling of response $em = $this->getEntityManager();
$addRunSql = 'INSERT INTO run(job_id, exitcode, output, runtime, timestamp,flags) VALUES (:job_id, :exitcode, :output, :runtime, :timestamp, :flags)';
$addRunStmt = $this->getEntityManager()->getConnection()->prepare($addRunSql); $run = new Run();
$addRunStmt->executeQuery([':job_id' => $jobid, ':exitcode' => $exitcode, 'output' => $output, 'runtime' => $runtime, ':timestamp' => $starttime, ':flags' => implode("", $flags)]); $run
->setJob($job)
->setExitcode($exitcode)
->setTimestamp($starttime)
->setRuntime($runtime)
->setOutput($output)
->setFlags(implode($flags));
$em->persist($run);
$em->flush();
} }
public function getLastRun(int $jobid): array public function getLastRun(Job $job): array
{ {
$lastRunSql = 'SELECT * FROM run WHERE job_id = :jobid ORDER BY timestamp DESC LIMIT 1'; $em = $this->getEntityManager();
$lastRun = $this->getEntityManager()->getConnection()->prepare($lastRunSql)->executeQuery([':jobid' => $jobid])->fetchAssociative(); $qb = $this->createQueryBuilder('run');
return $lastRun;
$lastrun = $qb
->where('run.job = :job')
->orderBy('run.timestamp', 'DESC')
->setParameter(':job', $job)
->getQuery()->getFirstResult();
return $lastrun;
} }
public function isSlowJob(int $jobid, int $timelimit = 5): bool public function isSlowJob(Job $job, int $timelimit = 5): bool
{ {
$slowJobSql = 'SELECT AVG(runtime) as average FROM run WHERE job_id = :jobid LIMIT 5'; $qb = $this->createQueryBuilder('run');
$slowJob = $this->getEntityManager()->getConnection()->prepare($slowJobSql)->executeQuery([':jobid' => $jobid])->fetchAssociative();
return $slowJob['average'] > $timelimit; $slowJob = $qb
->select('AVG(run.runtime) AS average')
->where('run.job = :job')
->setMaxResults(5)
->setParameter(':job', $job)
->getQuery()->getArrayResult();
return $slowJob[0]['average'] > $timelimit;
} }
public function cleanupRuns(array $jobids, int $maxage = NULL): int public function cleanupRuns(array $jobids, int $maxage = NULL): int
{ {
$jobRepo = $this->getEntityManager()->getRepository(Job::class); $em = $this->getEntityManager();
$allJobs = $jobRepo->getAllJobs(true); $jobRepo = $em->getRepository(Job::class);
$allJobs = [];
if(empty($jobids)) { if(empty($jobids)) {
$allJobs = $jobRepo->getAllJobs(true);
foreach($allJobs as $key=>$job) { foreach($allJobs as $key=>$job) {
$jobids[] = $key; $jobids[] = $key;
} }
} else {
foreach($jobids as $jobid) {
$job = $em->find($jobid);
$jobRepo->parseJob($job);
$allJobs[] = $job;
}
} }
$sqldelete = []; $qb = $this->createQueryBuilder('run');
$delete = $qb->delete();
if($maxage == NULL) { if($maxage == NULL) {
foreach ($allJobs as $key=>$job) { foreach ($allJobs as $key=>$job) {
$jobData = $job->getData(); $jobData = $job->getData();
if(isset($jobData['retention']) && in_array($key, $jobids)) { if(isset($jobData['retention']) && in_array($key, $jobids)) {
$sqldelete[] = '( job_id = :job' . $key . ' AND timestamp < :timestamp' . $key . ')'; $delete = $delete
$params[':job' . $key] = $key; ->orWhere(
$params[':timestamp' . $key] = time() - ($jobData['retention'] * 24 * 60 * 60); $qb->expr()->andX(
$qb->expr()->eq('run.job', ':job' . $key),
$qb->expr()->lt('run.timestamp', ':timestamp' . $key)
)
)
->setParameter(':job' . $key, $job)
->setParameter(':timestamp' . $key, time() - ($jobData['retention'] * 24 * 60 * 60));
} }
} }
} else { } else {
$sqljobids = '';
if(!empty($jobids)) { if(!empty($jobids)) {
$jobidsql = []; $jobexpr = $qb->expr()->orX();
foreach($jobids as $key=>$jobid){ foreach($allJobs as $key=>$job){
$jobidsql[] = ':job' . $key; $jobexpr->add('run.job = :job' . $key);
$params[':job' . $key] = $jobid; $delete = $delete->setParameter(':job' . $key, $job);
} }
$sqljobids = ' AND job_id in (' . implode(',', $jobidsql) . ')'; $delete = $delete
->where($jobexpr);
} }
$params[':timestamp'] = time() - ($maxage * 24 * 60 * 60); $delete = $delete
$sqldelete[] = 'timestamp < :timestamp' . $sqljobids; ->andWhere('run.timestamp < :timestamp')
} ->setParameter(':timestamp', time() - ($maxage * 24 * 60 * 60));
$sql = 'DELETE FROM run WHERE ' . implode(' OR ', $sqldelete);
try {
return $this->getEntityManager()->getConnection()->prepare($sql)->executeStatement($params);
} catch(Exception $exception) {
throw $exception;
} }
return $delete->getQuery()->execute();
} }
} }