Skip to content

Commit

Permalink
ajout de redis pour le cache des requêtes
Browse files Browse the repository at this point in the history
  • Loading branch information
Remi81 committed Jan 16, 2025
1 parent 73afa56 commit 4c96951
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 25 deletions.
24 changes: 24 additions & 0 deletions config/packages/cache.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
framework:
cache:
# Cache par défaut en filesystem
app: cache.adapter.filesystem

pools:
# Pools Doctrine en Redis
doctrine.metadata_cache_pool:
adapter: cache.adapter.redis
provider: '%env(REDIS_URL)%'
default_lifetime: 86400
doctrine.query_cache_pool:
adapter: cache.adapter.redis
provider: '%env(REDIS_URL)%'
default_lifetime: 86400
doctrine.result_cache_pool:
adapter: cache.adapter.redis
provider: '%env(REDIS_URL)%'
default_lifetime: 86400

# Pool Redis disponible pour les repositories
cache.redis:
adapter: cache.adapter.redis_tag_aware
provider: '%env(REDIS_URL)%'
default_lifetime: 3600
tags: true
# Unique name of your app: used to compute stable namespaces for cache keys.
#prefix_seed: your_vendor_name/app_name

Expand Down
27 changes: 9 additions & 18 deletions config/packages/doctrine.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ doctrine:
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
metadata_cache_driver:
type: pool
pool: doctrine.metadata_cache_pool
query_cache_driver:
type: pool
pool: doctrine.query_cache_pool
result_cache_driver:
type: pool
pool: doctrine.result_cache_pool

dql:
string_functions:
Expand Down Expand Up @@ -54,21 +63,3 @@ when@prod, when@staging:
orm:
auto_generate_proxy_classes: false
proxy_dir: '%kernel.build_dir%/doctrine/orm/Proxies'
query_cache_driver:
type: pool
pool: doctrine.system_cache_pool
result_cache_driver:
type: pool
pool: doctrine.result_cache_pool

framework:
cache:
pools:
doctrine.result_cache_pool:
adapter: cache.app
default_lifetime: 1800
max_items: 1000
doctrine.system_cache_pool:
adapter: cache.system
default_lifetime: 3600
max_items: 500
4 changes: 4 additions & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ services:
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones

cache.redis:
class: Symfony\Component\Cache\Adapter\TagAwareAdapter
parent: cache.app

# Register the LogoutListener service
App\EventListener\MyCustomLogoutListener:
tags:
Expand Down
3 changes: 3 additions & 0 deletions cron.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"jobs": [
{
"command": "45 2 * * * php bin/console at:cron:site:cache_clear"
},
{
"command": "0 3 * * * php bin/console at:cron:site:datas"
},
Expand Down
6 changes: 6 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
version: '3'
services:
redis:
image: redis:alpine
container_name: at_redis
ports:
- "6379:6379"

nginx:
image: nginx:stable-alpine
container_name: at_nginx
Expand Down
27 changes: 27 additions & 0 deletions src/Command/Cron/Site/ClearCacheCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace App\Command\Cron\Site;

use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(name: 'at:cron:site:cache_clear', description: 'Vide le cache Redis')]
class ClearCacheCommand extends Command
{
public function __construct(
private CacheItemPoolInterface $cache,
) {
parent::__construct();
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->cache->clear();
$output->writeln('Cache vidé avec succès');

return Command::SUCCESS;
}
}
52 changes: 45 additions & 7 deletions src/Repository/Aid/AidRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Contracts\Cache\ItemInterface;
use Symfony\Contracts\Cache\TagAwareCacheInterface;

/**
* @extends ServiceEntityRepository<Aid>
Expand All @@ -41,6 +43,7 @@ public function __construct(
ManagerRegistry $registry,
private ReferenceService $referenceService,
private StringService $stringService,
private TagAwareCacheInterface $cache,
) {
parent::__construct($registry, Aid::class);
}
Expand Down Expand Up @@ -1307,9 +1310,43 @@ public function getQueryBuilder(?array $params = null): QueryBuilder

public function findForSearch(?array $params = null): array
{
$qb = $this->getQueryBuilderForSearch($params);
$results = $qb->getQuery()
->getResult();
// Création d'une clé de cache unique basée sur les paramètres
$cacheKey = 'aids_search_'.hash('xxh128', serialize([
'params' => $params,
'date' => (new \DateTime())->format('Y-m-d'),
]));

$results = $this->cache->get($cacheKey, function (ItemInterface $item) use ($params) {
// Expire le lendemain à 4h du matin
$tomorrow = new \DateTime('tomorrow 4:00:00');
$expiresIn = $tomorrow->getTimestamp() - time();

$item->expiresAfter($expiresIn);

// Ajout de tags pour pouvoir invalider des groupes spécifiques
$tags = ['aids', 'search_results'];

// Ajout de tags spécifiques basés sur les paramètres
if (isset($params['perimeter'])) {
$tags[] = 'perimeter_'.$params['perimeter'];
}
if (isset($params['categories'])) {
foreach ($params['categories'] as $category) {
$tags[] = 'category_'.$category;
}
}

$item->tag($tags);

// Exécution de la requête originale
$qb = $this->getQueryBuilderForSearch($params);
if ($params['projectReference'] ?? null) {
$qb->leftJoin('a.projectReferences', 'pr')
->addSelect('pr');
}

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

$return = [];
foreach ($results as $result) {
Expand Down Expand Up @@ -1719,7 +1756,7 @@ public function getQueryBuilderForSearch(?array $params = null): QueryBuilder
$simpleWordsString = !empty($synonyms['simple_words_string'])
? $this->stringService->sanitizeBooleanSearch($synonyms['simple_words_string'])
: null;

$sqlScore = '';

if ($originalName) {
Expand Down Expand Up @@ -1768,10 +1805,10 @@ public function getQueryBuilderForSearch(?array $params = null): QueryBuilder
$transformedTerms = array_map(function ($term) {
return false !== strpos($term, ' ') ? '"'.$term.'"' : $term;
}, $requiredKeywordReferencesName);

// on transforme le tableau en string pour la recherche fulltext
$requiredKeywordReferencesNameString = implode(' ', $transformedTerms);

$qb->andWhere('
MATCH_AGAINST(a.name, a.nameInitial, a.description, a.eligibility, a.projectExamples) '
.'AGAINST (:requireKeywordReferencesString_'.$key.' IN BOOLEAN MODE) > 0 '
Expand Down Expand Up @@ -1815,12 +1852,13 @@ public function getQueryBuilderForSearch(?array $params = null): QueryBuilder
// Découper le terme en mots
$words = explode(' ', $object);
// Ajouter * à la fin de chaque mot
$words = array_map(fn($word) => $word . '*', $words);
$words = array_map(fn ($word) => $word.'*', $words);
// Réassembler les mots en une seule chaîne
$string = implode(' ', $words);
if (count($words) > 1) {
$string = '"'.$string.'"';
}

return $string;
}, $objects);

Expand Down

0 comments on commit 4c96951

Please sign in to comment.