Skip to content

Commit

Permalink
perf: Do not execute RealmSerializationGroupNormalizer if there are…
Browse files Browse the repository at this point in the history
… no realms setup with a serialization_group.
  • Loading branch information
ambroisemaupate committed Jun 7, 2024
1 parent 8c87683 commit 32da06d
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 8 deletions.
2 changes: 1 addition & 1 deletion lib/RoadizCoreBundle/src/Entity/Realm.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public function setSerializationGroup(?string $serializationGroup): Realm
{
$this->serializationGroup = null !== $serializationGroup ?
(new AsciiSlugger())->slug($serializationGroup, '_')->lower()->toString() :
(new AsciiSlugger())->slug($this->getName(), '_')->lower()->toString();
null;
return $this;
}

Expand Down
32 changes: 32 additions & 0 deletions lib/RoadizCoreBundle/src/Realm/RealmResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ public function getRealms(?Node $node): array
return $this->managerRegistry->getRepository(Realm::class)->findByNode($node);
}

public function getRealmsWithSerializationGroup(?Node $node): array
{
if (null === $node) {
return [];
}
return $this->managerRegistry->getRepository(Realm::class)->findByNodeWithSerializationGroup($node);
}

public function isGranted(RealmInterface $realm): bool
{
return $this->security->isGranted(RealmVoter::READ, $realm);
Expand Down Expand Up @@ -76,4 +84,28 @@ public function getDeniedRealms(): array
}
return $cacheItem->get();
}

public function hasRealms(): bool
{
$cacheItem = $this->cache->getItem('app_has_realms');
if (!$cacheItem->isHit()) {
$hasRealms = $this->managerRegistry->getRepository(Realm::class)->countBy([]) > 0;
$cacheItem->set($hasRealms);
$cacheItem->expiresAfter(new \DateInterval('PT2H'));
$this->cache->save($cacheItem);
}
return $cacheItem->get();
}

public function hasRealmsWithSerializationGroup(): bool
{
$cacheItem = $this->cache->getItem('app_has_realms_with_serialization_group');
if (!$cacheItem->isHit()) {
$hasRealms = $this->managerRegistry->getRepository(Realm::class)->countWithSerializationGroup() > 0;
$cacheItem->set($hasRealms);
$cacheItem->expiresAfter(new \DateInterval('PT2H'));
$this->cache->save($cacheItem);
}
return $cacheItem->get();
}
}
13 changes: 13 additions & 0 deletions lib/RoadizCoreBundle/src/Realm/RealmResolverInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,24 @@

interface RealmResolverInterface
{
/**
* @return bool Does current application has realms?
*/
public function hasRealms(): bool;
/**
* @return bool Does current application has realms with serialization groups?
*/
public function hasRealmsWithSerializationGroup(): bool;
/**
* @param Node|null $node
* @return RealmInterface[]
*/
public function getRealms(?Node $node): array;
/**
* @param Node|null $node
* @return RealmInterface[]
*/
public function getRealmsWithSerializationGroup(?Node $node): array;
public function isGranted(RealmInterface $realm): bool;

/**
Expand Down
9 changes: 9 additions & 0 deletions lib/RoadizCoreBundle/src/Repository/RealmRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,13 @@ public function findByNodeAndBehaviour(Node $node, string $realmBehaviour): arra

return $qb->getQuery()->getResult();
}

public function countWithSerializationGroup(): int
{
$qb = $this->createQueryBuilder('r');
$qb->select($qb->expr()->count('r'))
->andWhere($qb->expr()->isNotNull('r.serializationGroup'));

return intval($qb->getQuery()->getSingleScalarResult());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

namespace RZ\Roadiz\CoreBundle\Serializer\Normalizer;

use Doctrine\Persistence\ManagerRegistry;
use RZ\Roadiz\CoreBundle\Entity\NodesSources;
use RZ\Roadiz\CoreBundle\Entity\Realm;
use RZ\Roadiz\CoreBundle\Model\RealmInterface;
use RZ\Roadiz\CoreBundle\Realm\RealmResolver;
use RZ\Roadiz\CoreBundle\Security\Authorization\Voter\RealmVoter;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Stopwatch\Stopwatch;

final class RealmSerializationGroupNormalizer implements NormalizerInterface, NormalizerAwareInterface
{
Expand All @@ -21,7 +22,8 @@ final class RealmSerializationGroupNormalizer implements NormalizerInterface, No

public function __construct(
private readonly Security $security,
private readonly ManagerRegistry $managerRegistry
private readonly RealmResolver $realmResolver,
private readonly Stopwatch $stopwatch
) {
}

Expand All @@ -30,12 +32,15 @@ public function __construct(
*/
public function supportsNormalization(mixed $data, string $format = null, array $context = []): bool
{
if (!($data instanceof NodesSources)) {
return false;
}
// Make sure we're not called twice
if (isset($context[self::ALREADY_CALLED])) {
return false;
}

return $data instanceof NodesSources;
return $this->realmResolver->hasRealmsWithSerializationGroup();
}

public function getSupportedTypes(?string $format): array
Expand All @@ -51,6 +56,7 @@ public function getSupportedTypes(?string $format): array
*/
public function normalize(mixed $object, ?string $format = null, array $context = []): mixed
{
$this->stopwatch->start('realm-serialization-group-normalizer', 'serializer');
$realms = $this->getAuthorizedRealmsForObject($object);

foreach ($realms as $realm) {
Expand All @@ -60,18 +66,19 @@ public function normalize(mixed $object, ?string $format = null, array $context
}

$context[self::ALREADY_CALLED] = true;
$this->stopwatch->stop('realm-serialization-group-normalizer');

return $this->normalizer->normalize($object, $format, $context);
}

/**
* @return Realm[]
* @return RealmInterface[]
*/
private function getAuthorizedRealmsForObject(NodesSources $object): array
{
$realms = $this->managerRegistry->getRepository(Realm::class)->findByNode($object->getNode());
$realms = $this->realmResolver->getRealmsWithSerializationGroup($object->getNode());

return array_filter($realms, function (Realm $realm) {
return array_filter($realms, function (RealmInterface $realm) {
return $this->security->isGranted(RealmVoter::READ, $realm);
});
}
Expand Down

0 comments on commit 32da06d

Please sign in to comment.