Skip to content
Snippets Groups Projects
Commit e699246d authored by Jan-Hendrik Willms's avatar Jan-Hendrik Willms Committed by David Siegfried
Browse files

limit number of parallel requests and cache gained info, fixes #4358

Closes #4358

Merge request studip/studip!3161
parent 7e3801da
No related branches found
No related tags found
No related merge requests found
import axios from "axios";
interface ChunkedRequest {
url: string,
parameters: object,
resolve(value: any): any,
reject(): any,
}
export default class ChunkedRequester
{
#requests: ChunkedRequest[] = [];
readonly #delay: number;
readonly #limit: number;
#timeout: any = null;
constructor(limit: number = 16, delay: number = 500) {
if (limit < 1) {
throw new Error('Limit must be positive');
}
this.#limit = limit;
this.#delay = delay;
}
addRequest(url: string, parameters: object = {}): Promise<any>
{
return new Promise((resolve, reject) => {
this.#requests.push({
url,
parameters,
resolve,
reject
});
this.#startRequests();
});
}
#startRequests(): void
{
if (this.#requests.length === 0) {
return;
}
if (this.#requests.length < this.#limit) {
this.clearTimeout();
}
if (this.#timeout !== null) {
return;
}
this.#timeout = setTimeout(
() => {
Promise.all(
this.#requests
.splice(0, this.#limit)
.map(({url, parameters, resolve, reject}) => {
return axios.get(url, {params: parameters}).then(resolve, reject);
})
).then(() => {
this.clearTimeout();
this.#startRequests();
});
}
, this.#delay
);
}
clearTimeout(): void
{
clearTimeout(this.#timeout);
this.#timeout = null;
}
}
......@@ -222,7 +222,7 @@ export default {
courses: [],
assistiveLive: '',
subLevelsCourses: 0,
thisLevelCourses: 0,
thisLevelCourses: this.getCachedNodeCourseInfo(this.node.id, this.semester, this.semClass),
showingAllCourses: false
}
},
......
......@@ -245,7 +245,7 @@ export default {
courses: [],
assistiveLive: '',
subLevelsCourses: 0,
thisLevelCourses: 0,
thisLevelCourses: this.getCachedNodeCourseInfo(this.node.id, this.semester, this.semClass),
showingAllCourses: false
}
},
......
......@@ -32,22 +32,24 @@ export default {
},
data() {
return {
isLoading: false,
courseCount: 0,
courseCount: this.getCachedNodeCourseInfo(this.node, this.semester, this.semClass),
showingAllCourses: false
}
},
computed: {
isLoading() {
return this.courseCount === null;
}
},
methods: {
showAllCourses(state) {
this.showingAllCourses = state;
this.$emit('showAllCourses', state);
},
loadNodeInfo(node) {
this.isLoading = true;
this.getNodeCourseInfo(node, this.semester, this.semClass)
.then(info => {
this.courseCount = info?.data.courses;
this.isLoading = false;
this.courseCount = info?.data.courses ?? 0;
});
}
},
......
import axios from 'axios';
import ChunkedRequester from '@/assets/javascripts/lib/chunked-requester';
import Cache from '@/assets/javascripts/lib/cache';
const requester = new ChunkedRequester();
const cache = Cache.getInstance('tree-info/');
export const TreeMixin = {
data() {
......@@ -56,7 +61,10 @@ export const TreeMixin = {
{params: parameters}
);
},
async getNodeCourseInfo(node, semesterId, semClass = 0) {
getCachedNodeCourseInfo(node, semesterId, semClass) {
return cache.get(['course-info', node.id, semesterId, semClass].join('/')) ?? null;
},
getNodeCourseInfo(node, semesterId, semClass = 0) {
let parameters = {};
if (semesterId !== 'all' && semesterId !== '0') {
......@@ -67,10 +75,17 @@ export const TreeMixin = {
parameters['filter[semclass]'] = semClass;
}
return axios.get(
return requester.addRequest(
STUDIP.URLHelper.getURL('jsonapi.php/v1/tree-node/' + node.id + '/courseinfo'),
{ params: parameters }
);
parameters
).then(courseinfo => {
cache.set(
['course-info', node.id, semesterId, semClass].join('/'),
courseinfo.data.courses ?? 0,
3 * 60 * 60
);
return courseinfo;
});
},
nodeUrl(node_id, semester = null ) {
return STUDIP.URLHelper.getURL('', { node_id, semester })
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment