Improve system task/schedule/job handling

This commit is contained in:
Dennis Eichhorn 2017-11-17 13:37:01 +01:00
parent b4e50880d9
commit 543357c804
7 changed files with 178 additions and 361 deletions

View File

@ -27,23 +27,104 @@ namespace phpOMS\Utils\TaskSchedule;
class Cron extends SchedulerAbstract class Cron extends SchedulerAbstract
{ {
public function save()
{
}
/** /**
* Run command * Run command
* *
* @param string $cmd Command to run * @param string $cmd Command to run
* *
* @return array * @return string
*
* @throws \Exception
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function run(string $cmd) : array private function run(string $cmd) : string
{ {
// TODO: Implement run() method. $cmd = 'cd ' . escapeshellarg(dirname(self::$bin)) . ' && ' . basename(self::$bin) . ' ' . $cmd;
return [];
$pipes = [];
$desc = [
1 => ['pipe', 'w'],
2 => ['pipe', 'w'],
];
$resource = proc_open($cmd, $desc, $pipes, __DIR__, null);
$stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
foreach ($pipes as $pipe) {
fclose($pipe);
}
$status = trim((string) proc_close($resource));
if ($status == -1) {
throw new \Exception($stderr);
}
return trim($stdout);
}
/**
* Normalize run result for easier parsing
*
* @param string $raw Raw command output
*
* @return string Normalized string for parsing
*
* @since 1.0.0
*/
private function normalize(string $raw) : string
{
return str_replace("\r\n", "\n", $raw);
}
/**
* {@inheritdoc}
*/
public function getAll() : array
{
$lines = explode("\n", $this->normalize($this->run('-l')));
unset($lines[0]);
$jobs = [];
foreach ($lines as $line) {
if($line !== '' && strrpos($line, '#', -strlen($line)) === false) {
$jobs[] = CronJob::createWith(str_getcsv($line, ' '));
}
}
return $jobs;
}
/**
* {@inheritdoc}
*/
public function getAllByName(string $name, bool $exact = true) : array
{
$lines = explode("\n", $this->normalize($this->run('-l')));
unset($lines[0]);
if ($exact) {
$jobs = [];
foreach ($lines as $line) {
$csv = str_getcsv($line, ' ');
if($line !== '' && strrpos($line, '#', -strlen($line)) === false && $csv[5] === $name) {
$jobs[] = CronJob::createWith($csv);
}
}
} else {
$jobs = [];
foreach ($lines as $line) {
$csv = str_getcsv($line, ' ');
if($line !== '' && strrpos($line, '#', -strlen($line)) === false && stripos($csv[5], $name) !== false) {
$jobs[] = CronJob::createWith($csv);
}
}
}
return $jobs;
} }
} }

View File

@ -15,6 +15,9 @@ declare(strict_types = 1);
namespace phpOMS\Utils\TaskSchedule; namespace phpOMS\Utils\TaskSchedule;
use phpOMS\Validation\Base\DateTime;
/** /**
* CronJob class. * CronJob class.
* *
@ -24,83 +27,17 @@ namespace phpOMS\Utils\TaskSchedule;
* @link http://website.orange-management.de * @link http://website.orange-management.de
* @since 1.0.0 * @since 1.0.0
*/ */
class CronJob extends TaskAbstract implements \Serializable class CronJob extends TaskAbstract
{ {
/** /**
* Constructor. * {@inheritdoc}
*
* @param Interval $interval Interval
* @param string $cmd Command to execute
*
* @since 1.0.0
*/ */
public function __construct(Interval $interval = null, $cmd = '') public static function createWith(array $jobData) : TaskAbstract
{ {
if (!isset($interval)) { $job = new self($jobData[5], '');
$this->interval = new Interval();
} else {
$this->interval = $interval;
}
$this->command = $cmd; $job->setRun($jobData[5]);
}
/** return $job;
* Serialize cronjob.
*
* @return string
*
* @since 1.0.0
*/
public function serialize()
{
$minute = $this->printValue($this->interval->getMinute());
$hour = $this->printValue($this->interval->getHour());
$dayOfMonth = $this->printValue($this->interval->getDayOfMonth());
$month = $this->printValue($this->interval->getMonth());
$dayOfWeek = $this->printValue($this->interval->getDayOfWeek());
return $minute . ' ' . $hour . ' ' . $dayOfMonth . ' ' . $month . ' ' . $dayOfWeek . ' ' . $this->command;
}
/**
* Print value.
*
* @param array $value Element to serialize
*
* @return string
*
* @since 1.0.0
*/
private function printValue(array $value) : string
{
if (($count = count($value['dayOfWeek'])) > 0) {
$parsed = implode(',', $value['dayOfWeek']);
} elseif ($value['start'] !== 0 && $value['end']) {
$parsed = $value['start'] . '-' . $value['end'];
$count = 2;
} else {
$parsed = '*';
$count = 1;
}
if ($count === 0 && $value['step'] !== 0) {
$parsed .= '/' . $value['step'];
}
return $parsed;
}
/**
* Unserialize cronjob.
*
* @param string $serialized To unserialize
*
* @since 1.0.0
*/
public function unserialize($serialized)
{
// TODO: Implement unserialize() method.
} }
} }

View File

@ -137,7 +137,7 @@ class Interval implements \Serializable
*/ */
private function parseMinute(string $minute) : array private function parseMinute(string $minute) : array
{ {
return [$minute];
} }
/** /**
@ -151,7 +151,7 @@ class Interval implements \Serializable
*/ */
private function parseHour(string $hour) : array private function parseHour(string $hour) : array
{ {
return [$hour];
} }
/** /**
@ -165,7 +165,7 @@ class Interval implements \Serializable
*/ */
private function parseDayOfMonth(string $dayOfMonth) : array private function parseDayOfMonth(string $dayOfMonth) : array
{ {
return [$dayOfMonth];
} }
/** /**
@ -179,7 +179,7 @@ class Interval implements \Serializable
*/ */
private function parseMonth(string $month) : array private function parseMonth(string $month) : array
{ {
return [$month];
} }
/** /**
@ -193,7 +193,7 @@ class Interval implements \Serializable
*/ */
private function parseDayOfWeek(string $dayOfWeek) : array private function parseDayOfWeek(string $dayOfWeek) : array
{ {
return [$dayOfWeek];
} }
/** /**
@ -207,7 +207,7 @@ class Interval implements \Serializable
*/ */
private function parseYear(string $year) : array private function parseYear(string $year) : array
{ {
return [$year];
} }
/** /**

View File

@ -15,6 +15,9 @@ declare(strict_types = 1);
namespace phpOMS\Utils\TaskSchedule; namespace phpOMS\Utils\TaskSchedule;
use phpOMS\Validation\Base\DateTime;
/** /**
* Schedule class. * Schedule class.
* *
@ -24,43 +27,29 @@ namespace phpOMS\Utils\TaskSchedule;
* @link http://website.orange-management.de * @link http://website.orange-management.de
* @since 1.0.0 * @since 1.0.0
*/ */
class Schedule extends TaskAbstract implements \Serializable class Schedule extends TaskAbstract
{ {
/** /**
* Constructor. * {@inheritdoc}
*
* @param string $name Schedule name
* @param string $cmd Command to execute
*
* @since 1.0.0
*/ */
public function __construct(string $name, string $cmd = '') public static function createWith(array $jobData) : TaskAbstract
{ {
parent::__construct($name, $cmd); $job = new self($jobData[1], '');
}
/** $job->setRun($jobData[8]);
* String representation of object $job->setStatus($jobData[3]);
* @link http://php.net/manual/en/serializable.serialize.php
* @return string the string representation of the object or null
* @since 5.1.0
*/
public function serialize()
{
// TODO: Implement serialize() method.
}
/** if (DateTime::isValid($jobData[2])) {
* Constructs the object $job->setNextRunTime(new \DateTime($jobData[2]));
* @link http://php.net/manual/en/serializable.unserialize.php }
* @param string $serialized <p>
* The string representation of the object. if (DateTime::isValid($jobData[5])) {
* </p> $job->setLastRuntime(new \DateTime($jobData[5]));
* @return void }
* @since 5.1.0
*/ $job->setComment($jobData[10]);
public function unserialize($serialized) $job->addResult($jobData[6]);
{
// TODO: Implement unserialize() method. return $job;
} }
} }

View File

@ -96,85 +96,16 @@ abstract class SchedulerAbstract
} }
/** /**
* Add task * Create task
* *
* @param TaskAbstract $task Task to add * @param TaskAbstract
* *
* @return void * @return void
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function add(TaskAbstract $task) /* : void */ public function create(TaskAbstract $task) /* : void */
{ {
$this->tasks[$task->getId()] = $task; $this->run($task->getCommand());
} }
/**
* Remove task
*
* @param mixed $id Task id
*
* @return bool
*
* @since 1.0.0
*/
public function remove(string $id) : bool
{
if (isset($this->tasks[$id])) {
unset($this->tasks[$id]);
return true;
}
return false;
}
/**
* Get task
*
* @param mixed $id Task id
*
* @return TaskAbstract|null
*
* @since 1.0.0
*/
public function get(string $id)
{
return $this->tasks[$id] ?? null;
}
/**
* Get all tasks
*
* @return TaskAbstract[]
*
* @since 1.0.0
*/
public function getAll() : array
{
return $this->tasks;
}
/**
* Set task
*
* @param TaskAbstract $task Task to edit
*
* @return void
*
* @since 1.0.0
*/
public function set(TaskAbstract $task) /* : void */
{
$this->tasks[$task->getId()] = $task;
}
/**
* Save tasks
*
* @return void
*
* @since 1.0.0
*/
abstract public function save() /* : void */;
} }

View File

@ -50,22 +50,41 @@ abstract class TaskAbstract
*/ */
protected $run = ''; protected $run = '';
/**
* Status of the task
*
* @var string
* @since 1.0.0
*/
protected $status = ''; protected $status = '';
/**
* Next runtime
*
* @var \DateTime
* @since 1.0.0
*/
protected $nextRunTime = null; protected $nextRunTime = null;
/**
* Last runtime
*
* @var \DateTime
* @since 1.0.0
*/
protected $lastRunTime = null; protected $lastRunTime = null;
protected $start = null; /**
* Comment
protected $end = null; *
* @param string $name Name of the task
* @param string $cmd Command/script to run
*
* @var string
* @since 1.0.0
*/
protected $comment = ''; protected $comment = '';
protected $results = [];
protected $author = '';
public function __construct(string $name, string $cmd = '') { public function __construct(string $name, string $cmd = '') {
$this->id = $name; $this->id = $name;
$this->command = $cmd; $this->command = $cmd;
@ -84,7 +103,7 @@ abstract class TaskAbstract
} }
/** /**
* Get command. * Get command to create the task
* *
* @return string * @return string
* *
@ -96,7 +115,7 @@ abstract class TaskAbstract
} }
/** /**
* Set command. * Set command to create the task
* *
* @param string $command Command * @param string $command Command
* *
@ -110,7 +129,7 @@ abstract class TaskAbstract
} }
/** /**
* Get run. * Get command/script to run
* *
* @return string * @return string
* *
@ -122,7 +141,7 @@ abstract class TaskAbstract
} }
/** /**
* Set run. * Set script to run
* *
* @param string $run Command/script to run * @param string $run Command/script to run
* *
@ -213,84 +232,6 @@ abstract class TaskAbstract
$this->lastRunTime = $lastRunTime; $this->lastRunTime = $lastRunTime;
} }
/**
* Get start.
*
* @return \DateTime
*
* @since 1.0.0
*/
public function getStart()
{
return $this->start;
}
/**
* Set start.
*
* @param \DateTime $start Start
*
* @return void
*
* @since 1.0.0
*/
public function setStart(\DateTime $start) /* : void */
{
$this->start = $start;
}
/**
* Get end.
*
* @return \DateTime
*
* @since 1.0.0
*/
public function getEnd()
{
return $this->end;
}
/**
* Set end.
*
* @param \DateTime $end End
*
* @return void
*
* @since 1.0.0
*/
public function setEnd(\DateTime $end) /* : void */
{
$this->end = $end;
}
/**
* Get author.
*
* @return string
*
* @since 1.0.0
*/
public function getAuthor() : string
{
return $this->author;
}
/**
* Set author.
*
* @param string $author Author
*
* @return void
*
* @since 1.0.0
*/
public function setAuthor(string $author) /* : void */
{
$this->author = $author;
}
/** /**
* Get comment. * Get comment.
* *
@ -328,4 +269,15 @@ abstract class TaskAbstract
{ {
$this->results[] = $result; $this->results[] = $result;
} }
/**
* Create task based on job data
*
* @param array $jobData Raw job data
*
* @return TaskAbstract
*
* @since 1.0.0
*/
abstract public static function createWith(array $jobData) : TaskAbstract;
} }

View File

@ -28,14 +28,6 @@ use phpOMS\Validation\Base\DateTime;
*/ */
class TaskScheduler extends SchedulerAbstract class TaskScheduler extends SchedulerAbstract
{ {
/**
* {@inheritdoc}
*/
public function save() /* : void */
{
}
/** /**
* Run command * Run command
* *
@ -88,46 +80,6 @@ class TaskScheduler extends SchedulerAbstract
return str_replace("\r\n", "\n", $raw); return str_replace("\r\n", "\n", $raw);
} }
/**
* Parse a list of jobs
*
* @param array $jobData Csv data containing the job information
*
* @return TaskAbstract Parsed job
*
* @since 1.0.0
*/
private function parseJobList(array $jobData) : TaskAbstract
{
$job = TaskFactory::create($jobData[1], '');
$job->setRun($jobData[8]);
$job->setStatus($jobData[3]);
if (DateTime::isValid($jobData[2])) {
$job->setNextRunTime(new \DateTime($jobData[2]));
}
if (DateTime::isValid($jobData[5])) {
$job->setLastRuntime(new \DateTime($jobData[5]));
}
$job->setAuthor($jobData[7]);
$job->setComment($jobData[10]);
if (DateTime::isValid($jobData[20])) {
$job->setStart(new \DateTime($jobData[20]));
}
if (DateTime::isValid($jobData[21])) {
$job->setEnd(new \DateTime($jobData[21]));
}
$job->addResult($jobData[6]);
return $job;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -138,28 +90,12 @@ class TaskScheduler extends SchedulerAbstract
$jobs = []; $jobs = [];
foreach ($lines as $line) { foreach ($lines as $line) {
$jobs[] = $this->parseJobList(str_getcsv($line)); $jobs[] = Schedule::createWith(str_getcsv($line));
} }
return $jobs; return $jobs;
} }
/**
* {@inheritdoc}
*/
public function get(string $id)
{
// todo: implement
}
/**
* {@inheritdoc}
*/
public function getByName(string $name) : Schedule
{
// todo: implement
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -171,31 +107,22 @@ class TaskScheduler extends SchedulerAbstract
$jobs = []; $jobs = [];
foreach ($lines as $line) { foreach ($lines as $line) {
$jobs[] = $this->parseJobList(str_getcsv($line)); $jobs[] = Schedule::createWith(str_getcsv($line));
} }
} else { } else {
$lines = explode("\n", $this->normalize($this->run('/query /v /fo CSV'))); $lines = explode("\n", $this->normalize($this->run('/query /v /fo CSV')));
$jobs = [];
unset($lines[0]); unset($lines[0]);
$jobs = [];
foreach ($lines as $key => $line) { foreach ($lines as $key => $line) {
$line = str_getcsv($line); $line = str_getcsv($line);
if (strpos($line[1], $name) !== false) { if (stripos($line[1], $name) !== false) {
$jobs[] = $this->parseJobList($line); $jobs[] = Schedule::createWith($line);
} }
} }
} }
return $jobs; return $jobs;
} }
/**
* {@inheritdoc}
*/
public function create(Schedule $task)
{
// todo: implement
}
} }