From 4d4d7ad22921c177adef6ad32e02f80a2bcceee1 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 13 Nov 2023 13:02:12 +0100 Subject: [PATCH] MOBILE-4463 core: Implement cache invalidation --- src/core/classes/site.ts | 11 +++++ src/core/features/settings/pages/dev/dev.html | 8 ++++ src/core/features/settings/pages/dev/dev.ts | 20 +++++++- src/core/services/cache-manager.ts | 46 +++++++++++++++++++ src/core/services/sites.ts | 16 +++++++ 5 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 src/core/services/cache-manager.ts diff --git a/src/core/classes/site.ts b/src/core/classes/site.ts index e59beb358..6c1a98b95 100644 --- a/src/core/classes/site.ts +++ b/src/core/classes/site.ts @@ -65,6 +65,7 @@ import { CoreUserAuthenticatedSupportConfig } from '@features/user/classes/suppo import { CoreLoginHelper } from '@features/login/services/login-helper'; import { CorePath } from '@singletons/path'; import { CoreErrorLogs } from '@singletons/error-logs'; +import { CoreFilepool } from '@services/filepool'; /** * QR Code type enumeration. @@ -1435,6 +1436,16 @@ export class CoreSite { }, onProgress); } + /** + * Invalidates all caches related to the site. + */ + async invalidateCaches(): Promise { + await Promise.all([ + CoreFilepool.invalidateAllFiles(this.getId()), + this.invalidateWsCache(), + ]); + } + /** * Invalidates all the cache entries. * diff --git a/src/core/features/settings/pages/dev/dev.html b/src/core/features/settings/pages/dev/dev.html index b43b5f36b..3d4628aba 100644 --- a/src/core/features/settings/pages/dev/dev.html +++ b/src/core/features/settings/pages/dev/dev.html @@ -61,6 +61,14 @@ + + +

Invalidate caches

+
+ + + +
diff --git a/src/core/features/settings/pages/dev/dev.ts b/src/core/features/settings/pages/dev/dev.ts index 85ddbc612..dd4a6f48e 100644 --- a/src/core/features/settings/pages/dev/dev.ts +++ b/src/core/features/settings/pages/dev/dev.ts @@ -18,11 +18,12 @@ import { CoreLoginHelperProvider } from '@features/login/services/login-helper'; import { CoreSettingsHelper } from '@features/settings/services/settings-helper'; import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins'; import { CoreUserTours } from '@features/usertours/services/user-tours'; +import { CoreCacheManager } from '@services/cache-manager'; import { CoreConfig } from '@services/config'; import { CoreNavigator } from '@services/navigator'; import { CorePlatform } from '@services/platform'; import { CoreSites } from '@services/sites'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; /** @@ -178,6 +179,23 @@ export class CoreSettingsDevPage implements OnInit { CoreDomUtils.showToast('User tours have been reseted'); } + /** + * Invalidate app caches. + */ + async invalidateCaches(): Promise { + const success = await CoreDomUtils.showOperationModals('Invalidating caches', true, async () => { + await CoreCacheManager.invalidate(); + + return true; + }); + + if (!success) { + return; + } + + await CoreDomUtils.showToast('Caches invalidated', true, ToastDuration.LONG); + } + async setEnabledStagingSites(enabled: boolean): Promise { if (this.enableStagingSites === this.previousEnableStagingSites) { return; diff --git a/src/core/services/cache-manager.ts b/src/core/services/cache-manager.ts new file mode 100644 index 000000000..11c6d2c24 --- /dev/null +++ b/src/core/services/cache-manager.ts @@ -0,0 +1,46 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Injectable } from '@angular/core'; +import { makeSingleton } from '@singletons'; + +export type InvalidateCacheListener = () => unknown; + +/** + * Application caches manager. + */ +@Injectable({ providedIn: 'root' }) +export class CoreCacheManagerService { + + protected invalidateListeners: InvalidateCacheListener[] = []; + + /** + * Register a listener to call when cache is invalidated. + * + * @param listener Listener. + */ + registerInvalidateListener(listener: InvalidateCacheListener): void { + this.invalidateListeners.push(listener); + } + + /** + * Invalidate cache. + */ + async invalidate(): Promise { + await Promise.all(this.invalidateListeners.map(listener => listener())); + } + +} + +export const CoreCacheManager = makeSingleton(CoreCacheManagerService); diff --git a/src/core/services/sites.ts b/src/core/services/sites.ts index 7129238f8..fb045d5e8 100644 --- a/src/core/services/sites.ts +++ b/src/core/services/sites.ts @@ -66,6 +66,7 @@ import { CoreLang, CoreLangFormat } from '@services/lang'; import { CoreNative } from '@features/native/services/native'; import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper'; import { CoreAutoLogoutType, CoreAutoLogout } from '@features/autologout/services/autologout'; +import { CoreCacheManager } from '@services/cache-manager'; export const CORE_SITE_SCHEMAS = new InjectionToken('CORE_SITE_SCHEMAS'); export const CORE_SITE_CURRENT_SITE_ID_CONFIG = 'current_site_id'; @@ -124,6 +125,8 @@ export class CoreSitesProvider { delete this.siteTables[siteId]; }); + + CoreCacheManager.registerInvalidateListener(() => this.invalidateCaches()); } /** @@ -2108,6 +2111,19 @@ export class CoreSitesProvider { }; } + /** + * Invalidate all sites cache. + */ + protected async invalidateCaches(): Promise { + const sites = await this.getSites(); + + await Promise.all( + sites + .map(site => CoreSitesFactory.makeSite(site.id, site.siteUrl)) + .map(site => site.invalidateCaches()), + ); + } + } export const CoreSites = makeSingleton(CoreSitesProvider);