-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 47ec5dd
Showing
18 changed files
with
1,086 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
vendor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
namespace ColourStream\Bundle\CronBundle\Annotation; | ||
|
||
/** | ||
* @Annotation() | ||
* @Target("CLASS") | ||
*/ | ||
use Doctrine\Common\Annotations\Annotation; | ||
|
||
class CronJob extends Annotation | ||
{ | ||
public $value; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
|
||
namespace ColourStream\Bundle\CronBundle; | ||
|
||
use Symfony\Component\HttpKernel\Bundle\Bundle; | ||
|
||
class ColourStreamCronBundle extends Bundle | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
namespace ColourStream\Bundle\CronBundle\Command; | ||
use Symfony\Component\Console\Input\InputArgument; | ||
|
||
use Symfony\Component\Console\Output\OutputInterface; | ||
|
||
use Symfony\Component\Console\Input\InputInterface; | ||
|
||
use ColourStream\Bundle\CronBundle\Entity\CronJobResult; | ||
|
||
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; | ||
|
||
class CronDisableJobCommand extends ContainerAwareCommand | ||
{ | ||
protected function configure() | ||
{ | ||
$this->setName("cron:disable-job") | ||
->setDescription("Disables a cron job") | ||
->addArgument("job", InputArgument::REQUIRED, "Name of the job to disable"); | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output) | ||
{ | ||
$jobName = $input->getArgument('job'); | ||
$em = $this->getContainer()->get("doctrine.orm.entity_manager"); | ||
$jobRepo = $em->getRepository('ColourStreamCronBundle:CronJob'); | ||
|
||
$job = $jobRepo->findOneByCommand($jobName); | ||
if(!$job) | ||
{ | ||
$output->writeln("Couldn't find a job by the name of " . $jobName); | ||
return CronJobResult::FAILED; | ||
} | ||
|
||
$job->setEnabled(false); | ||
$em->flush(); | ||
|
||
$output->writeln("Disabled cron job by the name of " . $jobName); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php | ||
namespace ColourStream\Bundle\CronBundle\Command; | ||
use Symfony\Component\Console\Input\InputArgument; | ||
|
||
use Symfony\Component\Console\Output\OutputInterface; | ||
|
||
use Symfony\Component\Console\Input\InputInterface; | ||
|
||
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; | ||
|
||
class CronEnableJobCommand extends ContainerAwareCommand | ||
{ | ||
protected function configure() | ||
{ | ||
$this->setName("cron:enable-job") | ||
->setDescription("Enables a cron job") | ||
->addArgument("job", InputArgument::REQUIRED, "Name of the job to enable"); | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output) | ||
{ | ||
$jobName = $input->getArgument('job'); | ||
$em = $this->getContainer()->get("doctrine.orm.entity_manager"); | ||
$jobRepo = $em->getRepository('ColourStreamCronBundle:CronJob'); | ||
|
||
$job = $jobRepo->findOneByCommand($jobName); | ||
if(!$job) | ||
{ | ||
$output->writeln("Couldn't find a job by the name of " . $jobName); | ||
return CronJobResult::FAILED; | ||
} | ||
|
||
$job->setEnabled(true); | ||
$em->flush(); | ||
|
||
$output->writeln("Disabled cron job by the name of " . $jobName); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?php | ||
namespace ColourStream\Bundle\CronBundle\Command; | ||
|
||
use Fusion\Framework\CronBundle\Entity\CronJobResult; | ||
|
||
use Symfony\Component\Console\Output\OutputInterface; | ||
|
||
use Symfony\Component\Console\Input\InputInterface; | ||
|
||
use Symfony\Component\Console\Input\InputArgument; | ||
|
||
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; | ||
|
||
class CronPruneLogsCommand extends ContainerAwareCommand | ||
{ | ||
protected function configure() | ||
{ | ||
$this->setName("cron:pruneLogs") | ||
->setDescription("Prunes the logs for each cron job, leaving only recent failures and the most recent success") | ||
->addArgument('job', InputArgument::OPTIONAL, 'Operate only on this job'); | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output) | ||
{ | ||
$em = $this->getContainer()->get("doctrine.orm.entity_manager"); | ||
$job = $input->getArgument('job'); | ||
|
||
if($job) | ||
{ | ||
$output->writeln("Pruning logs for cron job $job"); | ||
} | ||
else | ||
{ | ||
$output->writeln("Pruning logs for all cron jobs"); | ||
} | ||
|
||
if($job) | ||
{ | ||
$jobObj = $em->getRepository('ColourStreamCronBundle:CronJob')->findOneByCommand($job); | ||
if(!$jobObj) | ||
{ | ||
$output->writeln("Couldn't find a job by the name of " . $job); | ||
return CronJobResult::FAILED; | ||
} | ||
|
||
$em->getRepository('ColourStreamCronBundle:CronJobResult')->deleteOldLogs($jobObj); | ||
} | ||
else | ||
{ | ||
$em->getRepository('ColourStreamCronBundle:CronJobResult')->deleteOldLogs(); | ||
} | ||
|
||
// Flush the EM | ||
$em->flush(); | ||
|
||
$output->writeln("Logs pruned successfully"); | ||
return CronJobResult::SUCCEEDED; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
<?php | ||
namespace ColourStream\Bundle\CronBundle\Command; | ||
use Doctrine\ORM\EntityManager; | ||
|
||
use Symfony\Component\Console\Input\ArgvInput; | ||
|
||
use ColourStream\Bundle\CronBundle\Entity\CronJobResult; | ||
|
||
use ColourStream\Bundle\CronBundle\Entity\CronJob; | ||
|
||
use Symfony\Component\Console\Output\OutputInterface; | ||
|
||
use Symfony\Component\Console\Input\InputInterface; | ||
|
||
use Symfony\Component\Console\Input\InputArgument; | ||
|
||
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; | ||
|
||
class CronRunCommand extends ContainerAwareCommand | ||
{ | ||
protected function configure() | ||
{ | ||
$this->setName("cron:run") | ||
->setDescription("Runs any currently schedule cron jobs") | ||
->addArgument("job", InputArgument::OPTIONAL, "Run only this job (if enabled)"); | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output) | ||
{ | ||
$start = microtime(true); | ||
$em = $this->getContainer()->get("doctrine.orm.entity_manager"); | ||
$jobRepo = $em->getRepository('ColourStreamCronBundle:CronJob'); | ||
|
||
$jobsToRun = array(); | ||
if($jobName = $input->getArgument('job')) | ||
{ | ||
try | ||
{ | ||
$jobObj = $jobRepo->findOneByCommand($jobName); | ||
if($jobObj->getEnabled()) | ||
{ | ||
$jobsToRun = array($jobObj); | ||
} | ||
} | ||
catch(\Exception $e) | ||
{ | ||
$output->writeln("Couldn't find a job by the name of $jobName"); | ||
return CronJobResult::FAILED; | ||
} | ||
} | ||
else | ||
{ | ||
$jobsToRun = $jobRepo->findDueTasks(); | ||
} | ||
|
||
$jobCount = count($jobsToRun); | ||
$output->writeln("Running $jobCount jobs:"); | ||
|
||
foreach($jobsToRun as $job) | ||
{ | ||
$this->runJob($job, $output, $em); | ||
} | ||
|
||
// Flush our results to the DB | ||
$em->flush(); | ||
|
||
$end = microtime(true); | ||
$duration = sprintf("%0.2f", $end-$start); | ||
$output->writeln("Cron run completed in $duration seconds"); | ||
} | ||
|
||
protected function runJob(CronJob $job, OutputInterface $output, EntityManager $em) | ||
{ | ||
$output->write("Running " . $job->getCommand() . ": "); | ||
|
||
try | ||
{ | ||
$commandToRun = $this->getApplication()->get($job->getCommand()); | ||
} | ||
catch(InvalidArgumentException $ex) | ||
{ | ||
$output->writeln(" skipped (command no longer exists)"); | ||
$this->recordJobResult($em, $job, 0, "Command no longer exists", CronJobResult::SKIPPED); | ||
|
||
// No need to reschedule non-existant commands | ||
return; | ||
} | ||
|
||
$emptyInput = new ArgvInput(); | ||
$jobOutput = new MemoryWriter(); | ||
|
||
$jobStart = microtime(true); | ||
try | ||
{ | ||
$returnCode = $commandToRun->execute($emptyInput, $jobOutput); | ||
} | ||
catch(\Exception $ex) | ||
{ | ||
$returnCode = CronJobResult::FAILED; | ||
$jobOutput->writeln(""); | ||
$jobOutput->writeln("Job execution failed with exception " . get_class($ex) . ":"); | ||
$jobOutput->writeln($ex->__toString()); | ||
} | ||
$jobEnd = microtime(true); | ||
|
||
// Clamp the result to accepted values | ||
if($returnCode < CronJobResult::RESULT_MIN || $returnCode > CronJobResult::RESULT_MAX) | ||
{ | ||
$returnCode = CronJobResult::FAILED; | ||
} | ||
|
||
// Output the result | ||
$statusStr = "unknown"; | ||
if($returnCode == CronJobResult::SKIPPED) | ||
{ | ||
$statusStr = "skipped"; | ||
} | ||
elseif($returnCode == CronJobResult::SUCCEEDED) | ||
{ | ||
$statusStr = "succeeded"; | ||
} | ||
elseif($returnCode == CronJobResult::FAILED) | ||
{ | ||
$statusStr = "failed"; | ||
} | ||
|
||
$durationStr = sprintf("%0.2f", $jobEnd-$jobStart); | ||
$output->writeln("$statusStr in $durationStr seconds"); | ||
|
||
// Record the result | ||
$this->recordJobResult($em, $job, $jobEnd-$jobStart, $jobOutput->getOutput(), $returnCode); | ||
|
||
// And update the job with it's next scheduled time | ||
$newTime = new \DateTime(); | ||
$newTime = $newTime->add(new \DateInterval($job->getInterval())); | ||
$job->setNextRun($newTime); | ||
} | ||
|
||
protected function recordJobResult(EntityManager $em, CronJob $job, $timeTaken, $output, $resultCode) | ||
{ | ||
// Create a new CronJobResult | ||
$result = new CronJobResult(); | ||
$result->setJob($job); | ||
$result->setRunTime($timeTaken); | ||
$result->setOutput($output); | ||
$result->setResult($resultCode); | ||
|
||
// Then update associations and persist it | ||
$job->setMostRecentRun($result); | ||
$em->persist($result); | ||
} | ||
} |
Oops, something went wrong.