MOBILE-3817 filter: Apply update in background to filters

main
Dani Palou 2022-07-25 10:39:59 +02:00
parent 01df501cad
commit 979e995166
5 changed files with 138 additions and 76 deletions

View File

@ -2409,7 +2409,7 @@ export function chainRequests<T, O extends ObservableInput<any>>(
return source.subscribe({
next: async (value) => {
if (readingStrategy !== CoreSitesReadingStrategy.UPDATE_IN_BACKGROUND) {
if (readingStrategy !== CoreSitesReadingStrategy.STALE_WHILE_REVALIDATE) {
// Just use same strategy.
subscriber.next({ data: value, readingStrategy });

View File

@ -54,6 +54,9 @@ import { CoreDatabaseCachingStrategy } from '@classes/database/database-table-pr
import { SQLiteDB } from '@classes/sqlitedb';
import { CorePlatform } from '@services/platform';
import { CoreTime } from '@singletons/time';
import { Observable } from 'rxjs';
import { asyncObservable, firstValueFrom } from '@/core/utils/rxjs';
import { map } from 'rxjs/operators';
const ROOT_CACHE_KEY = 'mmCourse:';
@ -402,19 +405,36 @@ export class CoreCourseProvider {
* @return Promise resolved with the list of blocks.
* @since 3.7
*/
async getCourseBlocks(courseId: number, siteId?: string): Promise<CoreCourseBlock[]> {
const site = await CoreSites.getSite(siteId);
const params: CoreBlockGetCourseBlocksWSParams = {
courseid: courseId,
returncontents: true,
};
const preSets: CoreSiteWSPreSets = {
cacheKey: this.getCourseBlocksCacheKey(courseId),
updateFrequency: CoreSite.FREQUENCY_RARELY,
};
const result = await site.read<CoreCourseBlocksWSResponse>('core_block_get_course_blocks', params, preSets);
getCourseBlocks(courseId: number, siteId?: string): Promise<CoreCourseBlock[]> {
return firstValueFrom(this.getCourseBlocksObservable(courseId, { siteId }));
}
return result.blocks || [];
/**
* Get course blocks.
*
* @param courseId Course ID.
* @param options Options.
* @return Observable that returns the blocks.
* @since 3.7
*/
getCourseBlocksObservable(courseId: number, options: CoreSitesCommonWSOptions = {}): Observable<CoreCourseBlock[]> {
return asyncObservable(async () => {
const site = await CoreSites.getSite(options.siteId);
const params: CoreBlockGetCourseBlocksWSParams = {
courseid: courseId,
returncontents: true,
};
const preSets: CoreSiteWSPreSets = {
cacheKey: this.getCourseBlocksCacheKey(courseId),
updateFrequency: CoreSite.FREQUENCY_RARELY,
...CoreSites.getReadingStrategyPreSets(options.readingStrategy),
};
return site.readObservable<CoreCourseBlocksWSResponse>('core_block_get_course_blocks', params, preSets).pipe(
map(result => result.blocks),
);
});
}
/**
@ -908,7 +928,7 @@ export class CoreCourseProvider {
* @param includeStealthModules Whether to include stealth modules. Defaults to true.
* @return The reject contains the error message, else contains the sections.
*/
async getSections(
getSections(
courseId: number,
excludeModules: boolean = false,
excludeContents: boolean = false,
@ -916,63 +936,83 @@ export class CoreCourseProvider {
siteId?: string,
includeStealthModules: boolean = true,
): Promise<CoreCourseWSSection[]> {
const site = await CoreSites.getSite(siteId);
preSets = preSets || {};
preSets.cacheKey = this.getSectionsCacheKey(courseId);
preSets.updateFrequency = preSets.updateFrequency || CoreSite.FREQUENCY_RARELY;
const params: CoreCourseGetContentsParams = {
courseid: courseId,
};
params.options = [
{
name: 'excludemodules',
value: excludeModules,
},
{
name: 'excludecontents',
value: excludeContents,
},
];
if (this.canRequestStealthModules(site)) {
params.options.push({
name: 'includestealthmodules',
value: includeStealthModules,
});
}
let sections: CoreCourseGetContentsWSSection[];
try {
sections = await site.read('core_course_get_contents', params, preSets);
} catch {
// Error getting the data, it could fail because we added a new parameter and the call isn't cached.
// Retry without the new parameter and forcing cache.
preSets.omitExpires = true;
params.options.splice(-1, 1);
sections = await site.read('core_course_get_contents', params, preSets);
}
const siteHomeId = site.getSiteHomeId();
let showSections = true;
if (courseId == siteHomeId) {
const storedNumSections = site.getStoredConfig('numsections');
showSections = storedNumSections !== undefined && !!storedNumSections;
}
if (showSections !== undefined && !showSections && sections.length > 0) {
// Get only the last section (Main menu block section).
sections.pop();
}
// Add course to all modules.
return sections.map((section) => ({
...section,
modules: section.modules.map((module) => this.addAdditionalModuleData(module, courseId, section.id)),
return firstValueFrom(this.getSectionsObservable(courseId, {
excludeModules,
excludeContents,
includeStealthModules,
preSets,
siteId,
}));
}
/**
* Get the course sections.
*
* @param courseId The course ID.
* @param options Options.
* @return Observable that returns the sections.
*/
getSectionsObservable(
courseId: number,
options: CoreCourseGetSectionsOptions = {},
): Observable<CoreCourseWSSection[]> {
options.includeStealthModules = options.includeStealthModules ?? true;
return asyncObservable(async () => {
const site = await CoreSites.getSite(options.siteId);
const preSets: CoreSiteWSPreSets = {
...options.preSets,
cacheKey: this.getSectionsCacheKey(courseId),
updateFrequency: CoreSite.FREQUENCY_RARELY,
...CoreSites.getReadingStrategyPreSets(options.readingStrategy),
};
const params: CoreCourseGetContentsParams = {
courseid: courseId,
};
params.options = [
{
name: 'excludemodules',
value: !!options.excludeModules,
},
{
name: 'excludecontents',
value: !!options.excludeContents,
},
];
if (this.canRequestStealthModules(site)) {
params.options.push({
name: 'includestealthmodules',
value: !!options.includeStealthModules,
});
}
return site.readObservable<CoreCourseGetContentsWSSection[]>('core_course_get_contents', params, preSets).pipe(
map(sections => {
const siteHomeId = site.getSiteHomeId();
let showSections = true;
if (courseId == siteHomeId) {
const storedNumSections = site.getStoredConfig('numsections');
showSections = storedNumSections !== undefined && !!storedNumSections;
}
if (showSections !== undefined && !showSections && sections.length > 0) {
// Get only the last section (Main menu block section).
sections.pop();
}
// Add course to all modules.
return sections.map((section) => ({
...section,
modules: section.modules.map((module) => this.addAdditionalModuleData(module, courseId, section.id)),
}));
}),
);
});
}
/**
* Get cache key for section WS call.
*
@ -1933,3 +1973,13 @@ export type CoreCourseStoreModuleViewedOptions = {
timeaccess?: number;
siteId?: string;
};
/**
* Options for getSections.
*/
export type CoreCourseGetSectionsOptions = CoreSitesCommonWSOptions & {
excludeModules?: boolean;
excludeContents?: boolean;
includeStealthModules?: boolean; // Defaults to true.
preSets?: CoreSiteWSPreSets;
};

View File

@ -15,7 +15,7 @@
import { Injectable } from '@angular/core';
import { CoreNetwork } from '@services/network';
import { CoreSites } from '@services/sites';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreFilterDelegate } from './filter-delegate';
import {
CoreFilter,
@ -31,6 +31,7 @@ import { CoreEvents, CoreEventSiteData } from '@singletons/events';
import { CoreLogger } from '@singletons/logger';
import { CoreSite } from '@classes/site';
import { CoreCourseHelper } from '@features/course/services/course-helper';
import { firstValueFrom } from '@/core/utils/rxjs';
/**
* Helper service to provide filter functionalities.
@ -75,7 +76,11 @@ export class CoreFilterHelperProvider {
* @return Promise resolved with the contexts.
*/
async getBlocksContexts(courseId: number, siteId?: string): Promise<CoreFiltersGetAvailableInContextWSParamContext[]> {
const blocks = await CoreCourse.getCourseBlocks(courseId, siteId);
// Use stale while revalidate, but always use the first value. If data is updated it will be stored in DB.
const blocks = await firstValueFrom(CoreCourse.getCourseBlocksObservable(courseId, {
readingStrategy: CoreSitesReadingStrategy.STALE_WHILE_REVALIDATE,
siteId,
}));
const contexts: CoreFiltersGetAvailableInContextWSParamContext[] = [];
@ -153,7 +158,12 @@ export class CoreFilterHelperProvider {
* @return Promise resolved with the contexts.
*/
async getCourseModulesContexts(courseId: number, siteId?: string): Promise<CoreFiltersGetAvailableInContextWSParamContext[]> {
const sections = await CoreCourse.getSections(courseId, false, true, undefined, siteId);
// Use stale while revalidate, but always use the first value. If data is updated it will be stored in DB.
const sections = await firstValueFrom(CoreCourse.getSectionsObservable(courseId, {
excludeContents: true,
readingStrategy: CoreSitesReadingStrategy.STALE_WHILE_REVALIDATE,
siteId,
}));
const contexts: CoreFiltersGetAvailableInContextWSParamContext[] = [];

View File

@ -15,8 +15,8 @@
import { Injectable } from '@angular/core';
import { CoreNetwork } from '@services/network';
import { CoreSites } from '@services/sites';
import { CoreSite } from '@classes/site';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
import { CoreWSExternalWarning } from '@services/ws';
import { CoreTextUtils } from '@services/utils/text';
import { CoreFilterDelegate } from './filter-delegate';
@ -284,13 +284,15 @@ export class CoreFilterProvider {
const data: CoreFiltersGetAvailableInContextWSParams = {
contexts: contextsToSend,
};
const preSets = {
const preSets: CoreSiteWSPreSets = {
cacheKey: this.getAvailableInContextsCacheKey(contextsToSend),
updateFrequency: CoreSite.FREQUENCY_RARELY,
splitRequest: {
param: 'contexts',
maxLength: 300,
},
// Use stale while revalidate, but always use the first value. If data is updated it will be stored in DB.
...CoreSites.getReadingStrategyPreSets(CoreSitesReadingStrategy.STALE_WHILE_REVALIDATE),
};
const result = await site.read<CoreFilterGetAvailableInContextResult>(

View File

@ -1796,7 +1796,7 @@ export class CoreSitesProvider {
getFromCache: false,
emergencyCache: false,
};
case CoreSitesReadingStrategy.UPDATE_IN_BACKGROUND:
case CoreSitesReadingStrategy.STALE_WHILE_REVALIDATE:
return {
updateInBackground: true,
getFromCache: true,
@ -2023,7 +2023,7 @@ export const enum CoreSitesReadingStrategy {
PREFER_CACHE,
ONLY_NETWORK,
PREFER_NETWORK,
UPDATE_IN_BACKGROUND,
STALE_WHILE_REVALIDATE,
}
/**