Merge pull request #3851 from NoelDeMartin/MOBILE-4463

MOBILE-4463: Implement cache invalidation
main
Dani Palou 2023-11-15 07:53:06 +01:00 committed by GitHub
commit 38303aadf5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 119 additions and 8 deletions

View File

@ -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<void> {
await Promise.all([
CoreFilepool.invalidateAllFiles(this.getId()),
this.invalidateWsCache(),
]);
}
/**
* Invalidates all the cache entries.
*

View File

@ -368,7 +368,7 @@ export class CoreCompileProvider {
instance['CoreTime'] = CoreTime;
instance['CoreUrl'] = CoreUrl;
instance['CoreWindow'] = CoreWindow;
instance['CoreCache'] = CoreCache;
instance['CoreCache'] = CoreCache; // @deprecated since 4.4, plugins should use plain objects instead.
instance['CoreDelegate'] = CoreDelegate;
instance['CorePromisedValue'] = CorePromisedValue;
instance['CoreContentLinksHandlerBase'] = CoreContentLinksHandlerBase;

View File

@ -19,7 +19,7 @@
<ion-list class="list-item-limited-width">
<ion-item class="ion-text-wrap">
<ion-label>
<p class="item-heading">Text direction</p>
<p class="item-heading">Change text direction</p>
<p>{{ direction }}</p>
</ion-label>
<ion-toggle [(ngModel)]="rtl" (ionChange)="RTLChanged()" slot="end"></ion-toggle>
@ -58,7 +58,15 @@
<p class="item-heading">Reset user tours</p>
</ion-label>
<ion-button (click)="resetUserTours()" aria-label="Reset user tours" fill="clear" slot="end">
<ion-icon slot="icon-only" aria-hidden="true" name="fas-broom"></ion-icon>
<ion-icon slot="icon-only" aria-hidden="true" name="fas-repeat"></ion-icon>
</ion-button>
</ion-item>
<ion-item class="ion-text-wrap">
<ion-label>
<p class="item-heading">Invalidate caches</p>
</ion-label>
<ion-button (click)="invalidateCaches()" aria-label="Invalidate caches" fill="clear" slot="end">
<ion-icon slot="icon-only" aria-hidden="true" name="fas-rotate-right"></ion-icon>
</ion-button>
</ion-item>
@ -73,6 +81,9 @@
<h2>Disabled features</h2>
</ion-label>
</ion-item-divider>
<ion-item *ngIf="disabledFeatures.length === 0">
<ion-label>There are no features disabled</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngFor="let feature of disabledFeatures">
<ion-label>
<p class="item-heading">{{ feature }}</p>
@ -84,6 +95,9 @@
<h2>Site plugins</h2>
</ion-label>
</ion-item-divider>
<ion-item *ngIf="sitePlugins.length === 0">
<ion-label>There are no site plugins installed</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngFor="let plugin of sitePlugins">
<ion-label>
<p class="item-heading">{{ plugin.addon }} ({{plugin.component}})</p>

View File

@ -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';
/**
@ -104,7 +105,7 @@ export class CoreSettingsDevPage implements OnInit {
const disabledFeatures = (await CoreSites.getCurrentSite()?.getPublicConfig())?.tool_mobile_disabledfeatures;
this.disabledFeatures = disabledFeatures?.split(',') || [];
this.disabledFeatures = disabledFeatures?.split(',').filter(feature => feature.trim().length > 0) ?? [];
}
/**
@ -178,6 +179,23 @@ export class CoreSettingsDevPage implements OnInit {
CoreDomUtils.showToast('User tours have been reseted');
}
/**
* Invalidate app caches.
*/
async invalidateCaches(): Promise<void> {
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<void> {
if (this.enableStagingSites === this.previousEnableStagingSites) {
return;

View File

@ -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<void> {
await Promise.all(this.invalidateListeners.map(listener => listener()));
}
}
export const CoreCacheManager = makeSingleton(CoreCacheManagerService);

View File

@ -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<CoreSiteSchema[]>('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<void> {
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);

View File

@ -1,5 +1,11 @@
This files describes API changes in the Moodle Mobile app,
information provided here is intended especially for developers.
This file describes API changes in the Moodle App that affect site plugins, information provided here is intended especially for developers.
For more information about upgrading, read the official documentation: https://moodledev.io/general/app/upgrading/
=== 4.4.0 ===
- Starting with this release, this file will only document breaking changes for APIs exposed to site plugins. Internal changes will no longer be documented.
- CoreCache has been deprecated, use plain object as in-memory stores instead.
=== 4.3.0 ===
@ -7,7 +13,7 @@ information provided here is intended especially for developers.
- Font Awesome icon library has been updated to 6.4.0. But nothing has changed, only version number.
- The analytics system in the app has been refactored and some functions that could trigger analytics calls no longer do it, now you need to use CoreAnalytics instead. Some functions in CoreCourseLogHelper and CorePushNotificationsProvider have been deprecated.
- Due to the analytics refactor, the parameters of most log functions have changed.
- CoreCourseModuleHandlerData.buttons has been deprecated, now only one button in atribute button will be shown.
- CoreCourseModuleHandlerData.buttons has been deprecated, now only one button in attribute button will be shown.
=== 4.2.0 ===