Skip to content

Commit

Permalink
Merge b4ea83b into bedc146
Browse files Browse the repository at this point in the history
  • Loading branch information
tienvx committed Apr 9, 2022
2 parents bedc146 + b4ea83b commit 81911ce
Show file tree
Hide file tree
Showing 29 changed files with 1,044 additions and 814 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ jobs:
run: |
composer global require php-coveralls/php-coveralls
php-coveralls --coverage_clover=clover.xml -v
if: matrix.php-versions == '7.4'
if: matrix.php-versions == '8.0'
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"require": {
"php": "^8.0",
"ext-json": "*",
"doctrine/annotations": "^1.13",
"doctrine/doctrine-bundle": "^2.6",
"doctrine/orm": "^2.8",
"florianv/petrinet": "^2.1",
"jmgq/a-star": "^2.1",
Expand Down
3 changes: 2 additions & 1 deletion src/Entity/Bug.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
use Tienvx\Bundle\MbtBundle\Model\Bug as BugModel;
use Tienvx\Bundle\MbtBundle\Model\ProgressInterface;
use Tienvx\Bundle\MbtBundle\Model\TaskInterface;
use Tienvx\Bundle\MbtBundle\Repository\BugRepository;

/**
* @ORM\Entity
* @ORM\Entity(repositoryClass=BugRepository::class)
* @ORM\HasLifecycleCallbacks
*/
class Bug extends BugModel
Expand Down
3 changes: 2 additions & 1 deletion src/Entity/Task.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
use Tienvx\Bundle\MbtBundle\Model\Model\RevisionInterface;
use Tienvx\Bundle\MbtBundle\Model\Task as TaskModel;
use Tienvx\Bundle\MbtBundle\Model\Task\BrowserInterface;
use Tienvx\Bundle\MbtBundle\Repository\TaskRepository;

/**
* @ORM\Entity
* @ORM\Entity(repositoryClass=TaskRepository::class)
* @ORM\HasLifecycleCallbacks
*/
class Task extends TaskModel
Expand Down
71 changes: 12 additions & 59 deletions src/Reducer/HandlerTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,92 +2,45 @@

namespace Tienvx\Bundle\MbtBundle\Reducer;

use Doctrine\DBAL\LockMode;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Throwable;
use Tienvx\Bundle\MbtBundle\Exception\ExceptionInterface;
use Tienvx\Bundle\MbtBundle\Message\ReduceBugMessage;
use Tienvx\Bundle\MbtBundle\Model\BugInterface;
use Tienvx\Bundle\MbtBundle\Service\Bug\BugHelperInterface;
use Tienvx\Bundle\MbtBundle\Service\SelenoidHelperInterface;
use Tienvx\Bundle\MbtBundle\Service\StepRunnerInterface;
use Tienvx\Bundle\MbtBundle\Repository\BugRepositoryInterface;
use Tienvx\Bundle\MbtBundle\Service\StepsBuilderInterface;
use Tienvx\Bundle\MbtBundle\Service\StepsRunnerInterface;

abstract class HandlerTemplate implements HandlerInterface
{
protected EntityManagerInterface $entityManager;
protected BugRepositoryInterface $bugRepository;
protected MessageBusInterface $messageBus;
protected StepRunnerInterface $stepRunner;
protected StepsRunnerInterface $stepsRunner;
protected StepsBuilderInterface $stepsBuilder;
protected BugHelperInterface $bugHelper;
protected SelenoidHelperInterface $selenoidHelper;

public function __construct(
EntityManagerInterface $entityManager,
BugRepositoryInterface $bugRepository,
MessageBusInterface $messageBus,
StepRunnerInterface $stepRunner,
StepsBuilderInterface $stepsBuilder,
BugHelperInterface $bugHelper,
SelenoidHelperInterface $selenoidHelper
StepsRunnerInterface $stepsRunner,
StepsBuilderInterface $stepsBuilder
) {
$this->entityManager = $entityManager;
$this->bugRepository = $bugRepository;
$this->messageBus = $messageBus;
$this->stepRunner = $stepRunner;
$this->stepsRunner = $stepsRunner;
$this->stepsBuilder = $stepsBuilder;
$this->bugHelper = $bugHelper;
$this->selenoidHelper = $selenoidHelper;
}

/**
* @throws ExceptionInterface
*/
public function handle(BugInterface $bug, int $from, int $to): void
{
$newSteps = iterator_to_array($this->stepsBuilder->create($bug, $from, $to));
if (count($newSteps) >= count($bug->getSteps())) {
return;
}

$this->run($newSteps, $bug);
}

/**
* @throws ExceptionInterface
*/
protected function run(array $newSteps, BugInterface $bug): void
{
$driver = $this->selenoidHelper->createDriver($this->selenoidHelper->getCapabilities($bug));
try {
foreach ($newSteps as $step) {
$this->stepRunner->run($step, $bug->getTask()->getModelRevision(), $driver);
}
} catch (ExceptionInterface $exception) {
throw $exception;
} catch (Throwable $throwable) {
$this->stepsRunner->run($newSteps, $bug, false, function (Throwable $throwable) use ($bug, $newSteps): void {
if ($throwable->getMessage() === $bug->getMessage()) {
$this->updateSteps($bug, $newSteps);
$this->bugRepository->updateSteps($bug, $newSteps);
$this->messageBus->dispatch(new ReduceBugMessage($bug->getId()));
}
} finally {
$driver->quit();
}
}

public function updateSteps(BugInterface $bug, array $newSteps): void
{
$callback = function () use ($bug, $newSteps): void {
// Refresh the bug for the latest steps's length.
$this->entityManager->refresh($bug);

if (count($newSteps) <= count($bug->getSteps())) {
$this->entityManager->lock($bug, LockMode::PESSIMISTIC_WRITE);
$bug->getProgress()->setTotal(0);
$bug->getProgress()->setProcessed(0);
$bug->setSteps($newSteps);
}
};

$this->entityManager->transactional($callback);
});
}
}
54 changes: 54 additions & 0 deletions src/Repository/BugRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace Tienvx\Bundle\MbtBundle\Repository;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\DBAL\LockMode;
use Doctrine\Persistence\ManagerRegistry;
use Tienvx\Bundle\MbtBundle\Entity\Bug;
use Tienvx\Bundle\MbtBundle\Model\BugInterface;

class BugRepository extends ServiceEntityRepository implements BugRepositoryInterface
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Bug::class);
}

public function updateSteps(BugInterface $bug, array $newSteps): void
{
$this->getEntityManager()->wrapInTransaction(function () use ($bug, $newSteps): void {
// Refresh the bug for the latest steps's length.
$this->getEntityManager()->refresh($bug);

if (count($newSteps) <= count($bug->getSteps())) {
$this->getEntityManager()->lock($bug, LockMode::PESSIMISTIC_WRITE);
$bug->getProgress()->setTotal(0);
$bug->getProgress()->setProcessed(0);
$bug->setSteps($newSteps);
}
});
}

public function increaseProcessed(BugInterface $bug, int $processed = 1): void
{
$this->getEntityManager()->wrapInTransaction(function () use ($bug, $processed): void {
// Refresh the bug for the latest progress.
$this->getEntityManager()->refresh($bug);

$this->getEntityManager()->lock($bug, LockMode::PESSIMISTIC_WRITE);
$bug->getProgress()->increase($processed);
});
}

public function increaseTotal(BugInterface $bug, int $total): void
{
$this->getEntityManager()->wrapInTransaction(function () use ($bug, $total): void {
// Refresh the bug for the latest progress.
$this->getEntityManager()->refresh($bug);

$this->getEntityManager()->lock($bug, LockMode::PESSIMISTIC_WRITE);
$bug->getProgress()->setTotal($bug->getProgress()->getTotal() + $total);
});
}
}
15 changes: 15 additions & 0 deletions src/Repository/BugRepositoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Tienvx\Bundle\MbtBundle\Repository;

use Doctrine\Persistence\ObjectRepository;
use Tienvx\Bundle\MbtBundle\Model\BugInterface;

interface BugRepositoryInterface extends ObjectRepository
{
public function updateSteps(BugInterface $bug, array $newSteps): void;

public function increaseProcessed(BugInterface $bug, int $processed = 1): void;

public function increaseTotal(BugInterface $bug, int $total): void;
}
30 changes: 30 additions & 0 deletions src/Repository/TaskRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Tienvx\Bundle\MbtBundle\Repository;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Tienvx\Bundle\MbtBundle\Entity\Task;
use Tienvx\Bundle\MbtBundle\Model\TaskInterface;

class TaskRepository extends ServiceEntityRepository implements TaskRepositoryInterface
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Task::class);
}

public function startRunning(TaskInterface $task): void
{
$task->setRunning(true);
$this->getEntityManager()->flush();
}

public function stopRunning(TaskInterface $task): void
{
$task->setRunning(false);
// Running task take long time. Reconnect to flush changes.
$this->getEntityManager()->getConnection()->connect();
$this->getEntityManager()->flush();
}
}
13 changes: 13 additions & 0 deletions src/Repository/TaskRepositoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Tienvx\Bundle\MbtBundle\Repository;

use Doctrine\Persistence\ObjectRepository;
use Tienvx\Bundle\MbtBundle\Model\TaskInterface;

interface TaskRepositoryInterface extends ObjectRepository
{
public function startRunning(TaskInterface $task): void;

public function stopRunning(TaskInterface $task): void;
}

0 comments on commit 81911ce

Please sign in to comment.