Skip to content

Commit aad1aec

Browse files
committed
feat: Live update execution diagram as etl runs
1 parent e771b7f commit aad1aec

File tree

5 files changed

+96
-7
lines changed

5 files changed

+96
-7
lines changed

Repository/EtlExecutionRepository.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,33 @@
1414
*/
1515
class EtlExecutionRepository extends ServiceEntityRepository
1616
{
17-
public function __construct(ManagerRegistry $registry)
17+
public function __construct(protected readonly ManagerRegistry $registry)
1818
{
1919
parent::__construct($registry, EtlExecution::class);
2020
}
2121

2222
public function save(EtlExecution $execution)
2323
{
2424
$this->_em->persist($execution);
25-
$this->_em->flush();
25+
$this->_em->flush($execution);
26+
}
27+
28+
public function updateStepStats(EtlExecution $execution, string $stepStats)
29+
{
30+
/** @var \Doctrine\DBAL\Connection $connection */
31+
$connection = $this->registry->getConnection();
32+
33+
$query = $connection->createQueryBuilder()
34+
->update('EtlExecution', 'e')
35+
->set('e.stepStats', ':stepStats')
36+
->where('e.id = :executionId')
37+
->setParameter('stepStats', $stepStats)
38+
->setParameter('executionId', $execution->getId());
39+
$query->execute();
40+
41+
if ($connection->getTransactionNestingLevel() > 0) {
42+
$query->getConnection()->commit();
43+
}
2644
}
2745

2846
public function getCountInStatus(\DateTime $startTime, \DateTime $endTime, string $status): int

Services/ChainProcessorsManager.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,14 @@ public function executeFromEtlEntity(EtlExecution $execution, iterable $iterator
127127
// Start the process.
128128
$observerProcessTime = 0;
129129
$processor->process($iterator, $params, function (array $operationStates, int $processedItems, int $returnedItems, bool $hasFinished = false) use ($observerCallback, &$observerProcessTime, $execution) {
130-
$observerCallback($operationStates, $processedItems, $returnedItems, $hasFinished);
130+
if ($observerCallback) {
131+
$observerCallback($operationStates, $processedItems, $returnedItems, $hasFinished);
132+
}
131133

132134
if ((time() - $observerProcessTime) > 5 || $hasFinished) {
133-
$execution = $this->etlExecutionRepository->find($execution->getId());
134-
$execution->setStepStats(json_encode($operationStates));
135-
136-
$this->etlExecutionRepository->save($execution);
135+
$jsonStates = json_encode($operationStates);
136+
$execution->setStepStats($jsonStates);
137+
$this->etlExecutionRepository->updateStepStats($execution, $jsonStates);
137138
$observerProcessTime = time();
138139
}
139140
});

assets/controllers/graph_reload.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Controller } from '@hotwired/stimulus';
2+
import mermaid from 'mermaid';
3+
4+
export default class extends Controller {
5+
static values = { continueUpdate: Boolean, refreshInterval: Number, apiUrl: String }
6+
7+
async connect() {
8+
console.log(this.continueUpdateValue);
9+
console.log(this.refreshIntervalValue);
10+
console.log(this.apiUrlValue);
11+
// console.log(mermaid);
12+
13+
mermaid.initialize({startOnLoad: false});
14+
this.mermaid = await mermaid.run({
15+
nodes: [this.element],
16+
});
17+
18+
if (this.continueUpdateValue) {
19+
this.startTimer(this.refreshIntervalValue);
20+
}
21+
}
22+
23+
startTimer(timer) {
24+
let that = this;
25+
setTimeout(function () {
26+
fetch(that.apiUrlValue, {method: "get"})
27+
.then(response => {
28+
return response.json();
29+
}).then(async data => {
30+
if (data.continueUpdate === 'false') {
31+
location.reload()
32+
return;
33+
}
34+
35+
console.log(data);
36+
const {svg, bindFunctions} = await mermaid.render('run-graph', data.graph);
37+
that.element.innerHTML = svg;
38+
39+
that.startTimer(data.refreshInterval);
40+
})
41+
}, timer * 1000);
42+
}
43+
}

assets/package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "@oliverde8/php-etl-graph-reload",
3+
"description": "",
4+
"version": "1.0.0",
5+
"license": "MIT",
6+
"symfony": {
7+
"controllers": {
8+
"oliverde8-etl-graph-reload": {
9+
"main": "controllers/graph_reload.js",
10+
"name": "oliverde8-etl-graph-reload",
11+
"webpackMode": "eager",
12+
"fetch": "eager",
13+
"enabled": true
14+
}
15+
},
16+
"importmap": {
17+
"@hotwired/stimulus": "^3.0.0"
18+
}
19+
},
20+
"dependencies": {
21+
"mermaid": "^1.13"
22+
},
23+
"peerDependencies": {
24+
"@hotwired/stimulus": "^3.0.0"
25+
}
26+
}

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"type": "library",
44
"description": "Allow usage of the PHP-ETL library in symfony framework.",
55
"license": "MIT",
6+
"keywords": ["symfony-ux"],
67
"authors": [
78
{
89
"name": "Oliver de Cramer",

0 commit comments

Comments
 (0)