Skip to content

Commit d936034

Browse files
committed
fix: improve action tasks management
Use a cache instead of making unnecessary multiple API requests for retrieving the context of a running task
1 parent cb00b1c commit d936034

File tree

2 files changed

+81
-16
lines changed

2 files changed

+81
-16
lines changed

core/ui/src/mixins/notification.js

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { mapState, mapActions, mapGetters } from "vuex";
1+
import { mapState, mapActions, mapGetters, mapMutations } from "vuex";
22
import to from "await-to-js";
33
import {
44
UtilService,
@@ -22,7 +22,9 @@ export default {
2222
"setNotificationDrawerShownInStore",
2323
"deleteNotificationInStore",
2424
"setPollingTimerForTaskInStore",
25+
"getTaskContextFromCache",
2526
]),
27+
...mapMutations(["setTaskContextInCache", "refreshTaskContextInCache"]),
2628
createNotification(notification) {
2729
// fill missing attributes
2830
if (!notification.type) {
@@ -185,27 +187,40 @@ export default {
185187
return `${taskContext.action}-${result}${eventId}`;
186188
},
187189
async handleProgressTaskMessage(taskPath, taskId, payload) {
188-
const [err, contextResponse] = await to(this.getTaskContext(taskPath));
190+
let taskContext = await this.getTaskContextFromCache(taskId);
189191

190-
if (err) {
191-
console.error("error retrieving task info", err);
192-
return;
193-
}
192+
console.log("@@ handleProgressTaskMessage", taskId); ////
193+
console.log("@@ taskContext from cache", taskContext); ////
194194

195-
const taskStatus = payload.status;
195+
if (!taskContext) {
196+
console.log("@@ miss, calling context api..."); ////
196197

197-
if (!contextResponse.data.data) {
198-
console.warn(
199-
"task context not found, skipping",
200-
taskId,
201-
taskPath,
202-
payload
203-
);
204-
return;
198+
// fetch task context from API and store it in cache
199+
const [err, contextResponse] = await to(this.getTaskContext(taskPath));
200+
201+
if (err) {
202+
console.error("error retrieving task info", err);
203+
return;
204+
}
205+
206+
if (!contextResponse.data.data) {
207+
console.warn(
208+
"task context not found, skipping",
209+
taskId,
210+
taskPath,
211+
payload
212+
);
213+
return;
214+
}
215+
taskContext = contextResponse.data.data.context;
216+
this.setTaskContextInCache({ taskId, taskContext }); ////
217+
218+
console.log("@@ taskContext from api", taskContext); ////
205219
}
220+
console.log("@@ taskContext!", taskContext); ////
206221

207-
const taskContext = contextResponse.data.data.context;
208222
let taskResult;
223+
const taskStatus = payload.status;
209224

210225
if (["completed", "aborted", "validation-failed"].includes(taskStatus)) {
211226
// get output and error

core/ui/src/store/index.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ export default new Vuex.Store({
3434
description: "",
3535
},
3636
migratingApps: [],
37+
taskContextCache: new Map(),
38+
taskContextCacheSize: 50, //// 50?
3739
},
3840
getters: {
3941
unreadNotifications: (state, getters) => {
@@ -190,6 +192,37 @@ export default new Vuex.Store({
190192
setMigratingApps(state, migratingApps) {
191193
state.migratingApps = migratingApps;
192194
},
195+
refreshTaskContextInCache(state, payload) {
196+
console.log("@@ refreshTaskContextInCache", payload); ////
197+
198+
const taskId = payload.taskId;
199+
const taskContext = payload.taskContext;
200+
201+
// Refresh the item: delete and re-insert so it's "newest"
202+
state.taskContextCache.delete(taskId);
203+
state.taskContextCache.set(taskId, taskContext);
204+
},
205+
setTaskContextInCache(state, payload) {
206+
console.log("@@ setTaskContextInCache", payload); ////
207+
208+
const taskId = payload.taskId;
209+
const taskContext = payload.taskContext;
210+
211+
// If it already exists, delete it first to update the position
212+
if (state.taskContextCache.has(taskId)) {
213+
state.taskContextCache.delete(taskId);
214+
}
215+
216+
// Remove the oldest entry if limit is reached
217+
// .keys().next().value returns the first (oldest) key
218+
if (state.taskContextCache.size >= state.taskContextCacheSize) {
219+
const oldestKey = state.taskContextCache.keys().next().value;
220+
state.taskContextCache.delete(oldestKey);
221+
222+
console.log("@@ deleted old key", oldestKey); ////
223+
}
224+
state.taskContextCache.set(taskId, taskContext);
225+
},
193226
},
194227
actions: {
195228
setPollingTimerForTaskInStore(context, obj) {
@@ -282,6 +315,23 @@ export default new Vuex.Store({
282315
setMigratingAppsInStore(context, migratingApps) {
283316
context.commit("setMigratingApps", migratingApps);
284317
},
318+
getTaskContextFromCache: (context, taskId) => {
319+
console.log("@@ getTaskContextFromCache", taskId); ////
320+
321+
if (!context.state.taskContextCache.has(taskId)) {
322+
console.log("@@ cache MISS", taskId); ////
323+
324+
// The requested task ID is not in the cache
325+
return null;
326+
}
327+
const taskContext = context.state.taskContextCache.get(taskId);
328+
329+
console.log("@@ cache HIT", taskId, taskContext); ////
330+
331+
// Refresh the item: delete and re-insert so it's "newest"
332+
context.commit("refreshTaskContextInCache", { taskId, taskContext });
333+
return taskContext;
334+
},
285335
},
286336
});
287337

0 commit comments

Comments
 (0)