fix: lock domain purchase if already launched

This commit is contained in:
Maël Gangloff 2025-11-09 17:38:31 +01:00
parent 7f288c01e3
commit 66e2c25b18
No known key found for this signature in database
GPG Key ID: 11FDC81C24A7F629
5 changed files with 32 additions and 5 deletions

2
.env
View File

@ -42,7 +42,7 @@ CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
###> symfony/lock ###
# Choose one of the stores below
# postgresql+advisory://db_user:db_password@localhost/db_name
LOCK_DSN=flock
LOCK_DSN=redis://localhost:6379/lock?lazy=1
###< symfony/lock ###
###> symfony/mailer ###

View File

@ -23,6 +23,7 @@
"php": ">=8.4",
"ext-ctype": "*",
"ext-iconv": "*",
"ext-redis": "*",
"ext-simplexml": "*",
"api-platform/core": "^3.3",
"doctrine/dbal": "^3",

3
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "1db291e0d108c6bb06d447134f1250c6",
"content-hash": "97d6a4c9c86bc5a77dfdbc3e41e1deb5",
"packages": [
{
"name": "api-platform/core",
@ -15394,6 +15394,7 @@
"php": ">=8.4",
"ext-ctype": "*",
"ext-iconv": "*",
"ext-redis": "*",
"ext-simplexml": "*"
},
"platform-dev": [],

View File

@ -17,8 +17,11 @@ use App\Service\Provider\AbstractProvider;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\DependencyInjection\Attribute\Target;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Lock\Key;
use Symfony\Component\Lock\LockFactory;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
@ -43,7 +46,10 @@ final readonly class OrderDomainHandler
#[Autowire(service: 'service_container')]
private ContainerInterface $locator,
#[Autowire(param: 'influxdb_enabled')]
private bool $influxdbEnabled, private EntityManagerInterface $em, private DomainPurchaseRepository $domainPurchaseRepository,
private bool $influxdbEnabled, private EntityManagerInterface $em,
private DomainPurchaseRepository $domainPurchaseRepository,
#[Target('lock')]
private LockFactory $lockFactory,
) {
$this->sender = new Address($mailerSenderEmail, $mailerSenderName);
}
@ -72,6 +78,23 @@ final readonly class OrderDomainHandler
return;
}
$lock = $this->lockFactory->createLockFromKey(
new Key('domain_purchase.'.$domain->getLdhName().'.'.$connector->getId()),
ttl: 600,
autoRelease: false
);
if (!$lock->acquire()) {
$this->logger->notice('Purchase attempt is already launched for this domain name with this connector', [
'watchlist' => $message->watchlistToken,
'connector' => $connector->getId(),
'ldhName' => $message->ldhName,
'provider' => $connector->getProvider()->value,
]);
return;
}
$this->logger->notice('Watchlist is linked to a connector : a purchase attempt will be made for this domain name', [
'watchlist' => $message->watchlistToken,
'connector' => $connector->getId(),
@ -162,6 +185,8 @@ final readonly class OrderDomainHandler
$this->em->flush();
}
$lock->release();
throw $exception;
}
}

View File

@ -20,7 +20,7 @@ class DomainPurchaseRepository extends ServiceEntityRepository
{
return $this->createQueryBuilder('dp')
->select('COUNT(dp)')
->where('dp.domainOrderedAt not NULL')
->where('dp.domainOrderedAt IS NOT NULL')
->getQuery()->getSingleScalarResult();
}
@ -28,7 +28,7 @@ class DomainPurchaseRepository extends ServiceEntityRepository
{
return $this->createQueryBuilder('dp')
->select('COUNT(dp)')
->where('dp.domainOrderedAt is NULL')
->where('dp.domainOrderedAt IS NULL')
->getQuery()->getSingleScalarResult();
}
}