1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
<?php
declare(strict_types=1);
namespace Doctrine\Tests\ORM\Functional\Locking;
use Closure;
use Doctrine\DBAL\Connection;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\ORMSetup;
use Doctrine\Tests\TestUtil;
use GearmanWorker;
use InvalidArgumentException;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use function assert;
use function is_array;
use function microtime;
use function sleep;
use function unserialize;
class LockAgentWorker
{
/** @var EntityManagerInterface */
private $em;
public static function run(): void
{
$lockAgent = new LockAgentWorker();
$worker = new GearmanWorker();
$worker->addServer(
$_SERVER['GEARMAN_HOST'] ?? null,
$_SERVER['GEARMAN_PORT'] ?? 4730
);
$worker->addFunction('findWithLock', [$lockAgent, 'findWithLock']);
$worker->addFunction('dqlWithLock', [$lockAgent, 'dqlWithLock']);
$worker->addFunction('lock', [$lockAgent, 'lock']);
while ($worker->work()) {
if ($worker->returnCode() !== GEARMAN_SUCCESS) {
echo 'return_code: ' . $worker->returnCode() . "\n";
break;
}
}
}
protected function process($job, Closure $do): float
{
$fixture = $this->processWorkload($job);
$s = microtime(true);
$this->em->beginTransaction();
$do($fixture, $this->em);
sleep(1);
$this->em->rollback();
$this->em->clear();
$this->em->close();
$this->em->getConnection()->close();
return microtime(true) - $s;
}
public function findWithLock($job): float
{
return $this->process($job, static function ($fixture, $em): void {
$entity = $em->find($fixture['entityName'], $fixture['entityId'], $fixture['lockMode']);
});
}
public function dqlWithLock($job): float
{
return $this->process($job, static function ($fixture, $em): void {
$query = $em->createQuery($fixture['dql']);
assert($query instanceof Doctrine\ORM\Query);
$query->setLockMode($fixture['lockMode']);
$query->setParameters($fixture['dqlParams']);
$result = $query->getResult();
});
}
public function lock($job): float
{
return $this->process($job, static function ($fixture, $em): void {
$entity = $em->find($fixture['entityName'], $fixture['entityId']);
$em->lock($entity, $fixture['lockMode']);
});
}
/** @return mixed[] */
protected function processWorkload($job): array
{
echo 'Received job: ' . $job->handle() . ' for function ' . $job->functionName() . "\n";
$workload = $job->workload();
$workload = unserialize($workload);
if (! isset($workload['conn']) || ! is_array($workload['conn'])) {
throw new InvalidArgumentException('Missing Database parameters');
}
$this->em = $this->createEntityManager($workload['conn']);
if (! isset($workload['fixture'])) {
throw new InvalidArgumentException('Missing Fixture parameters');
}
return $workload['fixture'];
}
protected function createEntityManager(Connection $conn): EntityManagerInterface
{
$config = new Configuration();
TestUtil::configureProxies($config);
$config->setAutoGenerateProxyClasses(true);
$annotDriver = ORMSetup::createDefaultAnnotationDriver([__DIR__ . '/../../../Models/']);
$config->setMetadataDriverImpl($annotDriver);
$config->setMetadataCache(new ArrayAdapter());
$config->setQueryCache(new ArrayAdapter());
return new EntityManager($conn, $config);
}
}
LockAgentWorker::run();
|