diff --git a/.env b/.env index 21a4054d1..414a776c5 100644 --- a/.env +++ b/.env @@ -68,6 +68,7 @@ KEY_VAULT_SOURCE=ENVIRONMENT KEY_VAULT_JSON="{}" TRACK_SCREEN_INFO=false TRACK_SCREEN_INFO_UPDATE_INTERVAL_SECONDS=300 +RELATIONS_CHECKSUM_ENABLED=true ###< App ### ###> itk-dev/openid-connect-bundle ### diff --git a/CHANGELOG.md b/CHANGELOG.md index f896363bd..337284d18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ All notable changes to this project will be documented in this file. - Moved list components (search and checkboxes) around. - Aligned environment variable names. - Aligned with v. 2.6.0. +- Added relations checksum feature flag. ### NB! Prior to 3.x the project was split into separate repositories diff --git a/assets/client/app.jsx b/assets/client/app.jsx index 107e10c13..779f62bd3 100644 --- a/assets/client/app.jsx +++ b/assets/client/app.jsx @@ -221,6 +221,9 @@ function App({ preview, previewId }) { ClientConfigLoader.loadConfig().then((config) => { setDebug(config.debug ?? false); + + const relationChecksumEnabled = config.relationsChecksumEnabled; + logger.info(`Relation checksum enabled: ${relationChecksumEnabled}`); }); releaseService.checkForNewRelease().finally(() => { diff --git a/assets/client/data-sync/pull-strategy.js b/assets/client/data-sync/pull-strategy.js index 1d0dfd60d..5b4ea7eed 100644 --- a/assets/client/data-sync/pull-strategy.js +++ b/assets/client/data-sync/pull-strategy.js @@ -2,6 +2,7 @@ import isPublished from "../util/isPublished"; import logger from "../logger/logger"; import ApiHelper from "./api-helper"; import { cloneDeep } from "lodash"; +import ClientConfigLoader from "../util/client-config-loader.js"; /** * PullStrategy. @@ -195,6 +196,9 @@ class PullStrategy { return; } + const config = await ClientConfigLoader.loadConfig(); + const relationChecksumEnabled = config.relationsChecksumEnabled; + if (screen === null) { logger.warn(`Screen (${screenPath}) not loaded`); return; @@ -209,14 +213,15 @@ class PullStrategy { this.lastestScreenData?.relationsChecksum ?? null; if ( + relationChecksumEnabled === false || oldScreenChecksums === null || oldScreenChecksums?.campaigns !== newScreenChecksums?.campaigns || oldScreenChecksums?.inScreenGroups !== newScreenChecksums?.inScreenGroups ) { - logger.info(`Campaigns or screen groups modified.`); + logger.info(`Fetching campaigns.`); newScreen.campaignsData = await this.getCampaignsData(newScreen); } else { - logger.info(`Campaigns or screen groups not modified.`); + logger.info(`Campaigns data loaded from cache.`); newScreen.campaignsData = this.lastestScreenData.campaignsData; } @@ -262,29 +267,31 @@ class PullStrategy { // Get layout: Defines layout and regions. if ( + relationChecksumEnabled === false || this.lastestScreenData?.hasActiveCampaign || oldScreenChecksums === null || oldScreenChecksums?.layout !== newScreenChecksums?.layout ) { - logger.info(`Layout changed since last fetch.`); + logger.info(`Fetching layout.`); newScreen.layoutData = await this.apiHelper.getPath(newScreen.layout); } else { // Get layout: Defines layout and regions. - logger.info(`Layout not changed since last fetch.`); + logger.info(`Layout loaded from cache.`); newScreen.layoutData = this.lastestScreenData.layoutData; } // Fetch regions playlists: Yields playlists of slides for the regions if ( + relationChecksumEnabled === false || this.lastestScreenData?.hasActiveCampaign || oldScreenChecksums === null || oldScreenChecksums?.regions !== newScreenChecksums?.regions ) { - logger.info(`Regions changed since last fetch.`); + logger.info(`Fetching regions and slides for regions.`); const regions = await this.getRegions(newScreen.regions); newScreen.regionData = await this.getSlidesForRegions(regions); } else { - logger.info(`Regions not changed since last fetch.`); + logger.info(`Regions and slides for regions loaded from cache.`); newScreen.regionData = this.lastestScreenData.regionData; } } @@ -308,7 +315,7 @@ class PullStrategy { let previousSlide = null; - // Find slide in previous data for comparing relationsChecksum values. + // Find the slide in previous data for comparing relationsChecksum values. if ( this.lastestScreenData?.regionData[regionKey] && this.lastestScreenData.regionData[regionKey][playlistKey] && @@ -328,6 +335,7 @@ class PullStrategy { // Fetch template if it has changed. if ( + relationChecksumEnabled === false || oldSlideChecksums === null || newSlideChecksums.templateInfo !== oldSlideChecksums.templateInfo ) { @@ -342,6 +350,7 @@ class PullStrategy { ) { slide.templateData = fetchedTemplates[templatePath]; } else { + logger.info(`Fetching template data.`); const templateData = await this.apiHelper.getPath(templatePath); slide.templateData = templateData; @@ -350,6 +359,7 @@ class PullStrategy { } } } else { + logger.info(`Template data loaded from cache.`); slide.templateData = previousSlide.templateData; } @@ -363,6 +373,7 @@ class PullStrategy { // Fetch media if it has changed. if ( + relationChecksumEnabled === false || oldSlideChecksums === null || newSlideChecksums.media !== oldSlideChecksums.media ) { @@ -372,6 +383,7 @@ class PullStrategy { if (Object.prototype.hasOwnProperty.call(fetchedMedia, mediaId)) { nextMediaData[mediaId] = fetchedMedia[mediaId]; } else { + logger.info(`Fetching media data.`); const mediaData = await this.apiHelper.getPath(mediaId); nextMediaData[mediaId] = mediaData; @@ -383,11 +395,13 @@ class PullStrategy { slide.mediaData = nextMediaData; } else { + logger.info(`Media data loaded from cache.`); slide.mediaData = previousSlide.mediaData; } // Fetch feed. if (slide?.feed?.feedUrl !== undefined) { + logger.info(`Fetching feed data.`); slide.feedData = await this.apiHelper.getPath(slide.feed.feedUrl); } diff --git a/config/services.yaml b/config/services.yaml index 92b2c2d39..b62f35f7f 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -53,6 +53,10 @@ services: Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface: '@Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Authentication\AuthenticationFailureHandler' Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface: '@Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Authentication\AuthenticationSuccessHandler' + App\EventListener\RelationsChecksumListener: + arguments: + $enabled: '%env(bool:RELATIONS_CHECKSUM_ENABLED)%' + App\Controller\Admin\AdminConfigController: arguments: $rejseplanenApiKey: '%env(ADMIN_REJSEPLANEN_APIKEY)%' @@ -70,6 +74,7 @@ services: $pullStrategyInterval: '%env(int:CLIENT_PULL_STRATEGY_INTERVAL)%' $colorScheme: '%env(json:CLIENT_COLOR_SCHEME)%' $debug: '%env(bool:CLIENT_DEBUG)%' + $relationsChecksumEnabled: '%env(bool:RELATIONS_CHECKSUM_ENABLED)%' App\Feed\EventDatabaseApiV2FeedType: arguments: diff --git a/src/Controller/Client/ClientConfigController.php b/src/Controller/Client/ClientConfigController.php index 7bf324571..33e278072 100644 --- a/src/Controller/Client/ClientConfigController.php +++ b/src/Controller/Client/ClientConfigController.php @@ -20,6 +20,7 @@ public function __construct( private readonly int $pullStrategyInterval, private readonly array $colorScheme, private readonly bool $debug, + private readonly bool $relationsChecksumEnabled, ) {} public function __invoke(): Response @@ -32,6 +33,7 @@ public function __invoke(): Response 'schedulingInterval' => $this->schedulingInterval, 'colorScheme' => $this->colorScheme, 'debug' => $this->debug, + 'relationsChecksumEnabled' => $this->relationsChecksumEnabled, ]); } } diff --git a/src/EventListener/RelationsChecksumListener.php b/src/EventListener/RelationsChecksumListener.php index f822c8109..ce78efb3d 100644 --- a/src/EventListener/RelationsChecksumListener.php +++ b/src/EventListener/RelationsChecksumListener.php @@ -60,6 +60,10 @@ class RelationsChecksumListener 'playlist', 'screen_campaign', 'screen', 'screen_group_campaign', 'screen_group', 'playlist_screen_region', 'screen_layout_regions', 'screen_layout']; + public function __construct( + private readonly bool $enabled = false, + ) {} + /** * PrePersist listener. * @@ -73,6 +77,10 @@ class RelationsChecksumListener */ final public function prePersist(PrePersistEventArgs $args): void { + if (!$this->enabled) { + return; + } + $entity = $args->getObject(); switch ($entity::class) { @@ -162,6 +170,10 @@ final public function prePersist(PrePersistEventArgs $args): void */ final public function preUpdate(PreUpdateEventArgs $args): void { + if (!$this->enabled) { + return; + } + $entity = $args->getObject(); if ($entity instanceof RelationsChecksumInterface) { @@ -180,6 +192,10 @@ final public function preUpdate(PreUpdateEventArgs $args): void */ final public function preRemove(PreRemoveEventArgs $args): void { + if (!$this->enabled) { + return; + } + $entity = $args->getObject(); switch ($entity::class) { @@ -227,6 +243,10 @@ final public function preRemove(PreRemoveEventArgs $args): void */ final public function postFlush(PostFlushEventArgs $args): void { + if (!$this->enabled) { + return; + } + $connection = $args->getObjectManager()->getConnection(); $sqlQueries = self::getUpdateRelationsAtQueries(withWhereClause: true);