chg: fetch job status from redis in jobs view.

pull/7939/head
Luciano Righetti 2021-10-26 15:02:35 +02:00
parent 9bb95db27e
commit 7a727c028b
6 changed files with 83 additions and 58 deletions

View File

@ -548,7 +548,7 @@ CREATE TABLE IF NOT EXISTS `jobs` (
`message` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`progress` int(11) NOT NULL DEFAULT 0,
`org_id` int(11) NOT NULL DEFAULT 0,
`process_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`process_id` varchar(36) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`date_created` datetime NOT NULL,
`date_modified` datetime NOT NULL,
PRIMARY KEY (`id`)

View File

@ -6,7 +6,7 @@ App::uses('AppController', 'Controller');
*/
class JobsController extends AppController
{
public $components = array('Security' ,'RequestHandler', 'Session');
public $components = array('Security', 'RequestHandler', 'Session');
public $paginate = array(
'limit' => 20,
@ -31,7 +31,7 @@ class JobsController extends AppController
$jobs = $this->paginate();
foreach ($jobs as &$job) {
if ($job['Job']['process_id'] !== false) {
$job['Job']['job_status'] = $this->__jobStatusConverter(CakeResque::getJobStatus($job['Job']['process_id']));
$job['Job']['job_status'] = $this->getJobStatus($job['Job']['process_id']);
$job['Job']['failed'] = $job['Job']['job_status'] === 'Failed';
} else {
$job['Job']['job_status'] = 'Unknown';
@ -53,7 +53,7 @@ class JobsController extends AppController
'Error' => 'error'
);
$this->set('fields', $fields);
$this->set('response', CakeResque::getFailedJobLog($id));
$this->set('response', $this->getFailedJobLog($id));
$this->render('/Jobs/ajax/error');
}
@ -84,7 +84,7 @@ class JobsController extends AppController
throw new NotFoundException("Job with ID `$id` not found");
}
$output = [
'job_status' => $this->__jobStatusConverter(CakeResque::getJobStatus($job['Job']['process_id'])),
'job_status' => $this->getJobStatus($job['Job']['process_id']),
'progress' => (int)$job['Job']['progress'],
];
return $this->RestResponse->viewData($output, 'json');
@ -136,7 +136,7 @@ class JobsController extends AppController
if ($this->_isSiteAdmin()) {
$target = 'All events.';
} else {
$target = 'Events visible to: '.$this->Auth->user('Organisation')['name'];
$target = 'Events visible to: ' . $this->Auth->user('Organisation')['name'];
}
$id = $this->Job->cache($type, $this->Auth->user());
if ($this->_isRest()) {
@ -161,4 +161,26 @@ class JobsController extends AppController
$this->redirect(array('action' => 'index'));
}
}
private function getJobStatus(string $id): string
{
if (Configure::read('BackgroundJobs.use_resque')) {
return $this->__jobStatusConverter(CakeResque::getJobStatus($id));
}
$job = $this->Job->getBackgroundJobsTool()->getJob($id);
return $this->__jobStatusConverter($job->status());
}
private function getFailedJobLog(string $id): array
{
if (Configure::read('BackgroundJobs.use_resque')) {
return CakeResque::getFailedJobLog($id);
}
return [
'error' => $this->Job->getBackgroundJobsTool()->getJob($id)->error()
];
}
}

View File

@ -12,32 +12,16 @@ class BackgroundJob implements JsonSerializable
STATUS_FAILED = 3,
STATUS_COMPLETED = 4;
/**
* Job id
*
* @var string
*/
/** @var string */
private $id;
/**
* Command name
*
* @var string
*/
/** @var string */
private $command;
/**
* Command arguments
*
* @var array
*/
/** @var array */
private $args;
/**
* Whether to track the status of the job
*
* @var bool
*/
/** @var bool */
private $trackStatus;
/**
@ -54,32 +38,22 @@ class BackgroundJob implements JsonSerializable
*/
private $updatedAt;
/**
* Job status id
*
* @var integer
*/
/**@var integer */
private $status;
/**
* Job progress
*
* @var integer
*/
/** @var integer */
private $progress;
/**
* Job metadata
*
* @var array
*/
/** @var string */
private $output;
/** @var string */
private $error;
/** @var array */
private $metadata;
/**
* Process return code
*
* @var integer
*/
/** @var integer */
private $returnCode;
public function __construct(array $properties)
@ -91,6 +65,7 @@ class BackgroundJob implements JsonSerializable
$this->createdAt = $properties['createdAt'] ?? time();
$this->updatedAt = $properties['updatedAt'] ?? null;
$this->status = $properties['status'] ?? self::STATUS_WAITING;
$this->error = $properties['error'] ?? null;
$this->progress = $properties['progress'] ?? 0;
$this->metadata = $properties['metadata'] ?? [];
}
@ -118,9 +93,11 @@ class BackgroundJob implements JsonSerializable
);
$stdout = stream_get_contents($pipes[1]);
$this->setOutput($stdout);
fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
$this->setError($stderr);
fclose($pipes[2]);
$this->returnCode = proc_close($process);
@ -151,6 +128,8 @@ class BackgroundJob implements JsonSerializable
'createdAt' => $this->createdAt,
'updatedAt' => $this->updatedAt,
'status' => $this->status,
'output' => $this->output,
'error' => $this->error,
'metadata' => $this->metadata,
];
}
@ -195,6 +174,16 @@ class BackgroundJob implements JsonSerializable
return $this->status;
}
public function output(): string
{
return $this->output;
}
public function error(): string
{
return $this->error;
}
public function metadata(): array
{
return $this->metadata;
@ -210,6 +199,16 @@ class BackgroundJob implements JsonSerializable
$this->status = $status;
}
public function setOutput(string $output): void
{
$this->output = $output;
}
public function setError(string $error): void
{
$this->error = $error;
}
public function setProgress(int $progress): void
{
$this->progress = $progress;

View File

@ -120,7 +120,7 @@ class BackgroundJobsTool
* @param array $args Arguments passed to the job.
* @param boolean|null $trackStatus Whether to track the status of the job.
* @param array $metadata Related to the job.
* @param Job $job Relational database record representing the job.
* @param Job|null $job Relational database record representing the job.
* @return string Background Job Id.
* @throws InvalidArgumentExceptiony
*/
@ -134,13 +134,13 @@ class BackgroundJobsTool
): string {
if ($this->settings['use_resque']) {
$this->resqueEnqueue($queue, self::CMD_TO_SHELL_DICT[$command], $args, $trackStatus, $job);
return $this->resqueEnqueue($queue, self::CMD_TO_SHELL_DICT[$command], $args, $trackStatus, $job);
}
$this->validateQueue($queue);
$this->validateCommand($command);
$job = new BackgroundJob(
$backgroundJob = new BackgroundJob(
[
'id' => CakeText::uuid(),
'command' => $command,
@ -152,12 +152,16 @@ class BackgroundJobsTool
$this->RedisConnection->rpush(
$queue,
json_encode($job->jsonSerialize())
json_encode($backgroundJob->jsonSerialize())
);
$this->update($job);
$this->update($backgroundJob);
return $job->id();
if ($job) {
$job->saveField('process_id', $backgroundJob->id());
}
return $backgroundJob->id();
}
/**
@ -168,7 +172,7 @@ class BackgroundJobsTool
* @param string $class Class of the job.
* @param array $args Arguments passed to the job.
* @param boolean $trackStatus Whether to track the status of the job.
* @param Job $job Relational database record representing the job.
* @param Job|null $job Relational database record representing the job.
* @return string Job Id.
*/
private function resqueEnqueue(

View File

@ -4562,7 +4562,7 @@ class Event extends AppModel
$user['id']
],
true,
[],
[], // metadata
$job
);
}

View File

@ -3193,10 +3193,10 @@
"column_name": "process_id",
"is_nullable": "YES",
"data_type": "varchar",
"character_maximum_length": "32",
"character_maximum_length": "36",
"numeric_precision": null,
"collation_name": "utf8_bin",
"column_type": "varchar(32)",
"column_type": "varchar(36)",
"column_default": null,
"extra": ""
},
@ -6419,10 +6419,10 @@
"column_name": "process_id",
"is_nullable": "YES",
"data_type": "varchar",
"character_maximum_length": "32",
"character_maximum_length": "36",
"numeric_precision": null,
"collation_name": "latin1_swedish_ci",
"column_type": "varchar(32)",
"column_type": "varchar(36)",
"column_default": null,
"extra": ""
},