Make workflow run logs immutable

[MAILPOET-4463]
This commit is contained in:
John Oleksowicz
2022-09-12 12:33:03 -05:00
committed by Jan Jakeš
parent cdeea173b9
commit 6f8edfaec4
5 changed files with 2 additions and 57 deletions

View File

@ -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;
}
} }

View File

@ -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']);

View File

@ -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,

View File

@ -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);

View File

@ -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'));