Make workflow run logs immutable
[MAILPOET-4463]
This commit is contained in:
committed by
Jan Jakeš
parent
cdeea173b9
commit
6f8edfaec4
@ -120,7 +120,7 @@ class StepHandler {
|
|||||||
|
|
||||||
$stepType = $step->getType();
|
$stepType = $step->getType();
|
||||||
if (isset($this->stepRunners[$stepType])) {
|
if (isset($this->stepRunners[$stepType])) {
|
||||||
$log = $this->createWorkflowRunLog($workflowRun, $step, $args);
|
$log = new WorkflowRunLog($workflowRun->getId(), $step->getId(), $args);
|
||||||
try {
|
try {
|
||||||
$this->stepRunners[$stepType]->run($step, $workflow, $workflowRun);
|
$this->stepRunners[$stepType]->run($step, $workflow, $workflowRun);
|
||||||
$log->markCompleted();
|
$log->markCompleted();
|
||||||
@ -134,7 +134,7 @@ class StepHandler {
|
|||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$log->addError($e);
|
$log->addError($e);
|
||||||
}
|
}
|
||||||
$this->workflowRunLogStorage->updateWorkflowRunLog($log);
|
$this->workflowRunLogStorage->createWorkflowRunLog($log);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidStateException();
|
throw new InvalidStateException();
|
||||||
@ -161,17 +161,6 @@ class StepHandler {
|
|||||||
|
|
||||||
// enqueue next step
|
// enqueue next step
|
||||||
$this->actionScheduler->enqueue(Hooks::WORKFLOW_STEP, $nextStepArgs);
|
$this->actionScheduler->enqueue(Hooks::WORKFLOW_STEP, $nextStepArgs);
|
||||||
|
|
||||||
// TODO: allow long-running steps (that are not done here yet)
|
// TODO: allow long-running steps (that are not done here yet)
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createWorkflowRunLog(WorkflowRun $workflowRun, Step $step, array $args): WorkflowRunLog {
|
|
||||||
$log = new WorkflowRunLog($workflowRun->getId(), $step->getId(), $args);
|
|
||||||
$logId = $this->workflowRunLogStorage->createWorkflowRunLog($log);
|
|
||||||
$workflowRunLog = $this->workflowRunLogStorage->getWorkflowRunLog($logId);
|
|
||||||
if (!$workflowRunLog instanceof WorkflowRunLog) {
|
|
||||||
throw new InvalidStateException();
|
|
||||||
}
|
|
||||||
return $workflowRunLog;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,6 @@ class WorkflowRunLog {
|
|||||||
/** @var DateTimeImmutable */
|
/** @var DateTimeImmutable */
|
||||||
private $createdAt;
|
private $createdAt;
|
||||||
|
|
||||||
/** @var DateTimeImmutable */
|
|
||||||
private $updatedAt;
|
|
||||||
|
|
||||||
/** @var DateTimeImmutable|null */
|
/** @var DateTimeImmutable|null */
|
||||||
private $completedAt;
|
private $completedAt;
|
||||||
|
|
||||||
@ -58,7 +55,6 @@ class WorkflowRunLog {
|
|||||||
|
|
||||||
$now = new DateTimeImmutable();
|
$now = new DateTimeImmutable();
|
||||||
$this->createdAt = $now;
|
$this->createdAt = $now;
|
||||||
$this->updatedAt = $now;
|
|
||||||
|
|
||||||
$this->errors = [];
|
$this->errors = [];
|
||||||
$this->data = [];
|
$this->data = [];
|
||||||
@ -112,17 +108,12 @@ class WorkflowRunLog {
|
|||||||
return $this->createdAt;
|
return $this->createdAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUpdatedAt(): DateTimeImmutable {
|
|
||||||
return $this->updatedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toArray(): array {
|
public function toArray(): array {
|
||||||
return [
|
return [
|
||||||
'workflow_run_id' => $this->workflowRunId,
|
'workflow_run_id' => $this->workflowRunId,
|
||||||
'step_id' => $this->stepId,
|
'step_id' => $this->stepId,
|
||||||
'status' => $this->status,
|
'status' => $this->status,
|
||||||
'created_at' => $this->createdAt->format(DateTimeImmutable::W3C),
|
'created_at' => $this->createdAt->format(DateTimeImmutable::W3C),
|
||||||
'updated_at' => $this->updatedAt->format(DateTimeImmutable::W3C),
|
|
||||||
'completed_at' => $this->completedAt ? $this->completedAt->format(DateTimeImmutable::W3C) : null,
|
'completed_at' => $this->completedAt ? $this->completedAt->format(DateTimeImmutable::W3C) : null,
|
||||||
'args' => Json::encode($this->args),
|
'args' => Json::encode($this->args),
|
||||||
'errors' => Json::encode($this->errors),
|
'errors' => Json::encode($this->errors),
|
||||||
@ -159,7 +150,6 @@ class WorkflowRunLog {
|
|||||||
$workflowRunLog->data = Json::decode($data['data']);
|
$workflowRunLog->data = Json::decode($data['data']);
|
||||||
$workflowRunLog->args = Json::decode($data['args']);
|
$workflowRunLog->args = Json::decode($data['args']);
|
||||||
$workflowRunLog->createdAt = new DateTimeImmutable($data['created_at']);
|
$workflowRunLog->createdAt = new DateTimeImmutable($data['created_at']);
|
||||||
$workflowRunLog->updatedAt = new DateTimeImmutable($data['updated_at']);
|
|
||||||
|
|
||||||
if ($data['completed_at']) {
|
if ($data['completed_at']) {
|
||||||
$workflowRunLog->completedAt = new DateTimeImmutable($data['completed_at']);
|
$workflowRunLog->completedAt = new DateTimeImmutable($data['completed_at']);
|
||||||
|
@ -69,7 +69,6 @@ class Migrator {
|
|||||||
step_id varchar(255) NOT NULL,
|
step_id varchar(255) NOT NULL,
|
||||||
status varchar(255) NOT NULL,
|
status varchar(255) NOT NULL,
|
||||||
created_at timestamp NOT NULL,
|
created_at timestamp NOT NULL,
|
||||||
updated_at timestamp NOT NULL,
|
|
||||||
completed_at timestamp NULL DEFAULT NULL,
|
completed_at timestamp NULL DEFAULT NULL,
|
||||||
args longtext,
|
args longtext,
|
||||||
errors longtext,
|
errors longtext,
|
||||||
|
@ -28,21 +28,6 @@ class WorkflowRunLogStorage {
|
|||||||
return $this->wpdb->insert_id;
|
return $this->wpdb->insert_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateWorkflowRunLog(WorkflowRunLog $workflowRunLog): int {
|
|
||||||
$data = $workflowRunLog->toArray();
|
|
||||||
unset($data['id']);
|
|
||||||
$data['updated_at'] = (new \DateTimeImmutable())->format(\DateTimeImmutable::W3C);
|
|
||||||
$where = ['id' => $workflowRunLog->getId()];
|
|
||||||
|
|
||||||
$result = $this->wpdb->update($this->table, $data, $where);
|
|
||||||
|
|
||||||
if ($result === false) {
|
|
||||||
throw Exceptions::databaseError($this->wpdb->last_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getWorkflowRunLog(int $id): ?WorkflowRunLog {
|
public function getWorkflowRunLog(int $id): ?WorkflowRunLog {
|
||||||
$table = esc_sql($this->table);
|
$table = esc_sql($this->table);
|
||||||
$query = $this->wpdb->prepare("SELECT * FROM $table WHERE id = %d", $id);
|
$query = $this->wpdb->prepare("SELECT * FROM $table WHERE id = %d", $id);
|
||||||
|
@ -25,24 +25,6 @@ class WorkflowRunLogStorageTest extends \MailPoetTest {
|
|||||||
expect($preSave)->equals($fromDatabase->toArray());
|
expect($preSave)->equals($fromDatabase->toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUpdatingLogUpdatesUpdatedAtTimestamp() {
|
|
||||||
$log = new WorkflowRunLog(1, 'step-id', []);
|
|
||||||
$reflectionClass = new \ReflectionClass(WorkflowRunLog::class);
|
|
||||||
$updatedAt = $reflectionClass->getProperty('updatedAt');
|
|
||||||
$updatedAt->setAccessible(true);
|
|
||||||
$updatedAt->setValue($log, new \DateTimeImmutable('2022-09-07'));
|
|
||||||
$id = $this->storage->createWorkflowRunLog($log);
|
|
||||||
$log = $this->storage->getWorkflowRunLog($id);
|
|
||||||
$this->assertInstanceOf(WorkflowRunLog::class, $log);
|
|
||||||
$originalUpdatedAt = $log->getUpdatedAt();
|
|
||||||
$log->setData('key', 'value');
|
|
||||||
$this->assertInstanceOf(WorkflowRunLog::class, $log);
|
|
||||||
$this->storage->updateWorkflowRunLog($log);
|
|
||||||
$fromDatabase = $this->storage->getWorkflowRunLog($id);
|
|
||||||
$this->assertInstanceOf(WorkflowRunLog::class, $fromDatabase);
|
|
||||||
expect($fromDatabase->getUpdatedAt())->greaterThan($originalUpdatedAt);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testItStoresErrors() {
|
public function testItStoresErrors() {
|
||||||
$log = new WorkflowRunLog(1, 'step-id', []);
|
$log = new WorkflowRunLog(1, 'step-id', []);
|
||||||
$log->addError(new \Exception('test'));
|
$log->addError(new \Exception('test'));
|
||||||
|
Reference in New Issue
Block a user