MOBILE-3833 core: Save public config in cache

main
Dani Palou 2022-04-08 12:19:54 +02:00
parent d4695dd845
commit 0e74f73549
4 changed files with 92 additions and 7 deletions

View File

@ -41,7 +41,7 @@ import { CoreLogger } from '@singletons/logger';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
import { CoreIonLoadingElement } from './ion-loading'; import { CoreIonLoadingElement } from './ion-loading';
import { CoreLang } from '@services/lang'; import { CoreLang } from '@services/lang';
import { CoreSites } from '@services/sites'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { asyncInstance, AsyncInstance } from '../utils/async-instance'; import { asyncInstance, AsyncInstance } from '../utils/async-instance';
import { CoreDatabaseTable } from './database/database-table'; import { CoreDatabaseTable } from './database/database-table';
import { CoreDatabaseCachingStrategy } from './database/database-table-proxy'; import { CoreDatabaseCachingStrategy } from './database/database-table-proxy';
@ -1389,9 +1389,88 @@ export class CoreSite {
/** /**
* Get the public config of this site. * Get the public config of this site.
* *
* @param options Options.
* @return Promise resolved with public config. Rejected with an object if error, see CoreWSProvider.callAjax. * @return Promise resolved with public config. Rejected with an object if error, see CoreWSProvider.callAjax.
*/ */
async getPublicConfig(): Promise<CoreSitePublicConfigResponse> { async getPublicConfig(options: { readingStrategy?: CoreSitesReadingStrategy } = {}): Promise<CoreSitePublicConfigResponse> {
if (!this.db) {
return this.requestPublicConfig();
}
const method = 'tool_mobile_get_public_config';
const cacheId = this.getCacheId(method, {});
const cachePreSets: CoreSiteWSPreSets = {
getFromCache: true,
saveToCache: true,
emergencyCache: true,
...CoreSites.getReadingStrategyPreSets(options.readingStrategy),
};
if (this.offlineDisabled) {
// Offline is disabled, don't use cache.
cachePreSets.getFromCache = false;
cachePreSets.saveToCache = false;
cachePreSets.emergencyCache = false;
}
// Check for an ongoing identical request if we're not ignoring cache.
if (cachePreSets.getFromCache && this.ongoingRequests[cacheId]) {
const response = await this.ongoingRequests[cacheId];
return response;
}
const promise = this.getFromCache<CoreSitePublicConfigResponse>(method, {}, cachePreSets, false).catch(async () => {
if (cachePreSets.forceOffline) {
// Don't call the WS, just fail.
throw new CoreError(
Translate.instant('core.cannotconnect', { $a: CoreSite.MINIMUM_MOODLE_VERSION }),
);
}
// Call the WS.
try {
const config = await this.requestPublicConfig();
if (cachePreSets.saveToCache) {
this.saveToCache(method, {}, config, cachePreSets);
}
return config;
} catch (error) {
cachePreSets.omitExpires = true;
cachePreSets.getFromCache = true;
try {
return await this.getFromCache<CoreSitePublicConfigResponse>(method, {}, cachePreSets, true);
} catch {
throw error;
}
}
});
this.ongoingRequests[cacheId] = promise;
// Clear ongoing request after setting the promise (just in case it's already resolved).
try {
const response = await promise;
// We pass back a clone of the original object, this may prevent errors if in the callback the object is modified.
return response;
} finally {
// Make sure we don't clear the promise of a newer request that ignores the cache.
if (this.ongoingRequests[cacheId] === promise) {
delete this.ongoingRequests[cacheId];
}
}
}
/**
* Perform a request to the server to get the public config of this site.
*
* @return Promise resolved with public config.
*/
protected async requestPublicConfig(): Promise<CoreSitePublicConfigResponse> {
const preSets: CoreWSAjaxPreSets = { const preSets: CoreWSAjaxPreSets = {
siteUrl: this.siteUrl, siteUrl: this.siteUrl,
}; };

View File

@ -16,7 +16,7 @@ import { Component, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/co
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { CoreApp } from '@services/app'; import { CoreApp } from '@services/app';
import { CoreSites } from '@services/sites'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { CoreLoginHelper } from '@features/login/services/login-helper'; import { CoreLoginHelper } from '@features/login/services/login-helper';
@ -132,7 +132,9 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
* Get some data (like identity providers) from the site config. * Get some data (like identity providers) from the site config.
*/ */
protected async checkSiteConfig(site: CoreSite): Promise<void> { protected async checkSiteConfig(site: CoreSite): Promise<void> {
this.siteConfig = await CoreUtils.ignoreErrors(site.getPublicConfig()); this.siteConfig = await CoreUtils.ignoreErrors(site.getPublicConfig({
readingStrategy: CoreSitesReadingStrategy.PREFER_NETWORK,
}));
if (!this.siteConfig) { if (!this.siteConfig) {
return; return;

View File

@ -14,7 +14,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCronHandler } from '@services/cron'; import { CoreCronHandler } from '@services/cron';
import { CoreSites } from '@services/sites'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
@ -39,7 +39,9 @@ export class CoreLoginCronHandlerService implements CoreCronHandler {
// Do not check twice in the same 10 minutes. // Do not check twice in the same 10 minutes.
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
const config = await CoreUtils.ignoreErrors(site.getPublicConfig()); const config = await CoreUtils.ignoreErrors(site.getPublicConfig({
readingStrategy: CoreSitesReadingStrategy.ONLY_NETWORK,
}));
CoreUtils.ignoreErrors(CoreSites.checkApplication(config)); CoreUtils.ignoreErrors(CoreSites.checkApplication(config));
} }

View File

@ -897,7 +897,9 @@ export class CoreSitesProvider {
*/ */
protected async getPublicConfigAndCheckApplication(site: CoreSite): Promise<void> { protected async getPublicConfigAndCheckApplication(site: CoreSite): Promise<void> {
try { try {
const config = await site.getPublicConfig(); const config = await site.getPublicConfig({
readingStrategy: CoreSitesReadingStrategy.ONLY_NETWORK,
});
await this.checkApplication(config); await this.checkApplication(config);
} catch { } catch {