Skip to content

Commit

Permalink
Merge pull request #1393 from MTES-MCT/feature/1320-cache-data-dkpi
Browse files Browse the repository at this point in the history
[BO - Dashboard] Stratégie de cache sur les data-kpi du dashboard
  • Loading branch information
sfinx13 committed Jun 21, 2023
2 parents 37c65c0 + 60eb82b commit f9aefeb
Show file tree
Hide file tree
Showing 16 changed files with 464 additions and 61 deletions.
3 changes: 1 addition & 2 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ MAILER_DSN=smtp://histologe_mailer:1025
# MAILER_DSN=sendinblue+smtp://USERNAME:PASSWORD@default
DATABASE_URL="mysql://histologe:histologe@histologe_mysql:3307/histologe_db?serverVersion=5.7&charset=utf8"
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
FEATURE_WIDGET_RELANCE_ENABLE=0

###> knplabs/knp-snappy-bundle ###
WKHTMLTOPDF_PATH=wkhtmltopdf
Expand All @@ -32,7 +31,7 @@ ADMIN_EMAIL=support@histologe.beta.gouv.fr
NOTIFICATIONS_EMAIL=notifications@histologe.beta.gouv.fr
CONTACT_EMAIL=contact@histologe.beta.gouv.fr
USER_SYSTEM_EMAIL=admin@histologe.net
WIDGET_DATA_KPI_CACHE_EXPIRED_AFTER=30 #second
WIDGET_DATA_KPI_CACHE_EXPIRED_AFTER=3600 #second
WIDGET_AFFECTATION_PARTNER_CACHE_EXPIRED_AFTER=30 #second
WIDGET_SIGNALEMENT_ACCEPTED_NO_SUIVI_CACHE_EXPIRED_AFTER=30 #second
WIDGET_SIGNALEMENT_TERRITOIRE_CACHE_EXPIRED_AFTER=30 #second
Expand Down
3 changes: 1 addition & 2 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,11 @@ ADMIN_EMAIL=support@histologe.beta.gouv.fr
NOTIFICATIONS_EMAIL=notifications@histologe.beta.gouv.fr
CONTACT_EMAIL=contact@histologe.beta.gouv.fr
USER_SYSTEM_EMAIL=admin@histologe.net
WIDGET_DATA_KPI_CACHE_EXPIRED_AFTER=30 #second
WIDGET_DATA_KPI_CACHE_EXPIRED_AFTER=3600 #second
WIDGET_AFFECTATION_PARTNER_CACHE_EXPIRED_AFTER=30 #second
WIDGET_SIGNALEMENT_ACCEPTED_NO_SUIVI_CACHE_EXPIRED_AFTER=30 #second
WIDGET_SIGNALEMENT_TERRITOIRE_CACHE_EXPIRED_AFTER=30 #second
WIDGET_ESABORA_EVENTS_CACHE_EXPIRED_AFTER=3600 #second
FEATURE_WIDGET_RELANCE_ENABLE=0
### histologe ###

### object storage S3 ###
Expand Down
1 change: 0 additions & 1 deletion config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ services:
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
bind:
$projectDir: '%kernel.project_dir%'
$featureWidgetRelanceEnable: '%env(bool:FEATURE_WIDGET_RELANCE_ENABLE)%'
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
Expand Down
176 changes: 176 additions & 0 deletions src/DataFixtures/Files/Signalement.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,182 @@ signalements:
nb_occupants_logement: 3
situation_occupant: "1"
territory: "Bouches-du-Rhône"
tags:
- "Urgent"
situations:
- "la vie commune et le voisinage"
- "la sécurité des occupants"
- "l'état et propreté du logement"
criteres:
- "Les déchets sont mal stockés."
- "La protection incendie n’est pas adaptée."
- "Les sols sont humides."
criticites:
- "les déchets ne peuvent être stockés nulle part. Il y a des ordures stockées n’importe où à l'intérieur ou à l'extérieur du bâtiment."
- "il n’y a pas de détecteur OU l’évacuation du logement est complexe (une seule sortie étroite, étage élevé, absence de fenêtre, escalier peu praticable…)."
- "le sol ou la base des murs est très humide."
-
uuid: "00000000-0000-0000-2023-000000000016"
details: "Signalement Lorem Ipsum is simply dummy text of the printing and typesetting industry."
is_proprio_averti: 1
is_logement_social: 0
nb_adultes: "2"
is_allocataire: ""
nature_logement: "Appartement"
type_logement: "T2"
superficie: 30
loyer: 300
phone_number: 0621127286
adresse_occupant: "138 Rue Loubon"
cp_occupant: "13003"
ville_occupant: "Marseille"
statut: 1
reference: "2023-16"
geoloc: "{\"lng\":\"43.3117791\", \"lat\":\"5.3755551\"}"
created_at: "2023-01-03 17:06:33"
score: 100
etage_occupant: "0"
escalier_occupant: ""
mode_contact_proprio: "[\"\",\"t\\u00e9l\\u00e9phone\"]"
insee_occupant: "13203"
is_rsa: 0
type_energie_logement: "Electrique"
origine_signalement: ""
nb_occupants_logement: 3
situation_occupant: "1"
territory: "Bouches-du-Rhône"
tags:
- "Urgent"
situations:
- "la vie commune et le voisinage"
- "la sécurité des occupants"
- "l'état et propreté du logement"
criteres:
- "Les déchets sont mal stockés."
- "La protection incendie n’est pas adaptée."
- "Les sols sont humides."
criticites:
- "les déchets ne peuvent être stockés nulle part. Il y a des ordures stockées n’importe où à l'intérieur ou à l'extérieur du bâtiment."
- "il n’y a pas de détecteur OU l’évacuation du logement est complexe (une seule sortie étroite, étage élevé, absence de fenêtre, escalier peu praticable…)."
- "le sol ou la base des murs est très humide."
-
uuid: "00000000-0000-0000-2023-000000000017"
details: "Signalement Lorem Ipsum is simply dummy text of the printing and typesetting industry."
is_proprio_averti: 1
is_logement_social: 0
nb_adultes: "2"
is_allocataire: ""
nature_logement: "Appartement"
type_logement: "T2"
superficie: 30
loyer: 300
phone_number: 0621127286
adresse_occupant: "140 Rue Loubon"
cp_occupant: "13003"
ville_occupant: "Marseille"
statut: 1
reference: "2023-17"
geoloc: "{\"lng\":\"43.3117791\", \"lat\":\"5.3755551\"}"
created_at: "2023-06-16 15:06:33"
score: 100
etage_occupant: "0"
escalier_occupant: ""
mode_contact_proprio: "[\"\",\"t\\u00e9l\\u00e9phone\"]"
insee_occupant: "13203"
is_rsa: 0
type_energie_logement: "Electrique"
origine_signalement: ""
nb_occupants_logement: 3
situation_occupant: "1"
territory: "Bouches-du-Rhône"
tags:
- "Urgent"
situations:
- "la vie commune et le voisinage"
- "la sécurité des occupants"
- "l'état et propreté du logement"
criteres:
- "Les déchets sont mal stockés."
- "La protection incendie n’est pas adaptée."
- "Les sols sont humides."
criticites:
- "les déchets ne peuvent être stockés nulle part. Il y a des ordures stockées n’importe où à l'intérieur ou à l'extérieur du bâtiment."
- "il n’y a pas de détecteur OU l’évacuation du logement est complexe (une seule sortie étroite, étage élevé, absence de fenêtre, escalier peu praticable…)."
- "le sol ou la base des murs est très humide."
-
uuid: "00000000-0000-0000-2023-000000000018"
details: "Signalement Lorem Ipsum is simply dummy text of the printing and typesetting industry."
is_proprio_averti: 1
is_logement_social: 0
nb_adultes: "2"
is_allocataire: ""
nature_logement: "Appartement"
type_logement: "T2"
superficie: 30
loyer: 300
phone_number: 0621127286
adresse_occupant: "142 Rue Loubon"
cp_occupant: "13003"
ville_occupant: "Marseille"
statut: 1
reference: "2023-18"
geoloc: "{\"lng\":\"43.3117791\", \"lat\":\"5.3755551\"}"
created_at: "2023-06-16 16:06:33"
score: 100
etage_occupant: "0"
escalier_occupant: ""
mode_contact_proprio: "[\"\",\"t\\u00e9l\\u00e9phone\"]"
insee_occupant: "13203"
is_rsa: 0
type_energie_logement: "Electrique"
origine_signalement: ""
nb_occupants_logement: 3
situation_occupant: "1"
territory: "Bouches-du-Rhône"
tags:
- "Urgent"
situations:
- "la vie commune et le voisinage"
- "la sécurité des occupants"
- "l'état et propreté du logement"
criteres:
- "Les déchets sont mal stockés."
- "La protection incendie n’est pas adaptée."
- "Les sols sont humides."
criticites:
- "les déchets ne peuvent être stockés nulle part. Il y a des ordures stockées n’importe où à l'intérieur ou à l'extérieur du bâtiment."
- "il n’y a pas de détecteur OU l’évacuation du logement est complexe (une seule sortie étroite, étage élevé, absence de fenêtre, escalier peu praticable…)."
- "le sol ou la base des murs est très humide."
-
uuid: "00000000-0000-0000-2023-000000000019"
details: "Signalement ancien"
is_proprio_averti: 1
is_logement_social: 0
nb_adultes: "2"
is_allocataire: ""
nature_logement: "Appartement"
type_logement: "T2"
superficie: 30
loyer: 300
phone_number: 0621127286
adresse_occupant: "136 Rue Loubon"
cp_occupant: "13003"
ville_occupant: "Marseille"
statut: 2
reference: "2023-15"
geoloc: "{\"lng\":\"43.3117791\", \"lat\":\"5.3755551\"}"
created_at: "2023-06-16 17:06:33"
score: 100
etage_occupant: "0"
escalier_occupant: ""
mode_contact_proprio: "[\"\",\"t\\u00e9l\\u00e9phone\"]"
insee_occupant: "13203"
is_rsa: 0
type_energie_logement: "Electrique"
origine_signalement: ""
nb_occupants_logement: 3
situation_occupant: "1"
territory: "Bouches-du-Rhône"
tags:
- "Urgent"
situations:
Expand Down
8 changes: 8 additions & 0 deletions src/DataFixtures/Files/User.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ users:
is_generique: 0
is_mailing_active: 1
territory: "Bouches-du-Rhône"
-
email: admin-territoire-13-02@histologe.fr
roles: "[\"ROLE_ADMIN_TERRITORY\"]"
partner: "Partenaire 13-01"
statut: 1
is_generique: 0
is_mailing_active: 0
territory: "Bouches-du-Rhône"
-
email: admin-territoire-01-01@histologe.fr
roles: "[\"ROLE_ADMIN_TERRITORY\"]"
Expand Down
6 changes: 4 additions & 2 deletions src/Entity/Partner.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,11 @@ public function getId(): ?int
return $this->id;
}

public function setId($id): ?int
public function setId($id): self
{
return $this->id = $id;
$this->id = $id;

return $this;
}

public function getNom(): ?string
Expand Down
81 changes: 81 additions & 0 deletions src/EventSubscriber/CacheInvalidationSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace App\EventSubscriber;

use App\Entity\Notification;
use App\Entity\Signalement;
use App\Entity\User;
use App\Service\CacheCommonKeyGenerator;
use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface;
use Doctrine\ORM\Events;
use Doctrine\Persistence\Event\LifecycleEventArgs;
use Psr\Cache\InvalidArgumentException;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Contracts\Cache\TagAwareCacheInterface;

class CacheInvalidationSubscriber implements EventSubscriberInterface
{
public const CONTEXT_WIDGET_DATA_KPI = 'countDataKpi';

public function __construct(
readonly private TagAwareCacheInterface $dashboardCache,
readonly private CacheCommonKeyGenerator $cacheCommonKeyGenerator,
readonly private LoggerInterface $logger,
private readonly Security $security,
) {
}

public function getSubscribedEvents(): array
{
return [
Events::postPersist,
Events::postUpdate,
Events::postRemove,
];
}

public function postPersist(LifecycleEventArgs $args): void
{
$this->invalidateCacheWidgetDataKpi($args);
}

public function postUpdate(LifecycleEventArgs $args): void
{
$this->invalidateCacheWidgetDataKpi($args);
}

public function postRemove(LifecycleEventArgs $args): void
{
$this->invalidateCacheWidgetDataKpi($args);
}

public function supports(mixed $entity): bool
{
return $entity instanceof Signalement || $entity instanceof Notification;
}

private function invalidateCacheWidgetDataKpi(LifecycleEventArgs $args): void
{
$entity = $args->getObject();
if ($this->supports($entity)) {
/** @var User $user */
$user = $this->security->getUser();
$territory = $user?->getTerritory();
try {
if ($entity instanceof Signalement) {
$this->dashboardCache->invalidateTags(['data-kpi-'.$territory?->getZip()]);
} else {
$commonKey = $this->cacheCommonKeyGenerator->generate();
$key = self::CONTEXT_WIDGET_DATA_KPI
.'-'.$commonKey
.'-zip-'.$territory?->getZip()
.'-id-'.$user?->getId();
$this->dashboardCache->delete($key);
}
} catch (InvalidArgumentException $exception) {
$this->logger->error(sprintf('Invalidate cache failed %s', $exception->getMessage()));
}
}
}
}
22 changes: 22 additions & 0 deletions src/Service/CacheCommonKeyGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace App\Service;

use App\Entity\User;
use Symfony\Bundle\SecurityBundle\Security;

class CacheCommonKeyGenerator
{
public function __construct(private readonly Security $security)
{
}

public function generate(): ?string
{
/** @var User $user */
$user = $this->security->getUser();
$role = $user?->getRoles();

return \is_array($role) ? array_shift($role).'-partnerId-'.$user->getPartner()->getId() : null;
}
}
8 changes: 4 additions & 4 deletions src/Service/DashboardWidget/WidgetDataKpi.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
class WidgetDataKpi
{
public function __construct(
private array $widgetCards,
private CountSignalement $countSignalement,
private CountSuivi $countSuivi,
private CountUser $countUser
private readonly array $widgetCards,
private readonly CountSignalement $countSignalement,
private readonly CountSuivi $countSuivi,
private readonly CountUser $countUser
) {
}

Expand Down
Loading

0 comments on commit f9aefeb

Please sign in to comment.