|
117 | 117 | <script lang="ts"> |
118 | 118 | import { useDialogPluginComponent } from 'quasar'; |
119 | 119 | import ctfnote from 'src/ctfnote'; |
120 | | -import { Ctf, makeId } from 'src/ctfnote/models'; |
| 120 | +import { Ctf, makeId, Id, Task } from 'src/ctfnote/models'; |
121 | 121 | import parsers, { ParsedTask } from 'src/ctfnote/parsers'; |
122 | 122 | import { defineComponent, ref } from 'vue'; |
123 | 123 | import TaskTagsList from 'src/components/Task/TaskTagsList.vue'; |
@@ -281,11 +281,69 @@ export default defineComponent({ |
281 | 281 | })); |
282 | 282 | }, |
283 | 283 | async createTasks(tasks: ParsedTask[]) { |
284 | | - for (const task of tasks) { |
285 | | - const r = await this.createTask(this.ctf.id, task); |
286 | | - const newTask = r?.data?.createTask?.task; |
287 | | - if (newTask) { |
288 | | - await this.addTagsForTask(task.tags, makeId(newTask.id)); |
| 284 | + const batchSize = 10; |
| 285 | + for (let i = 0; i < tasks.length; i += batchSize) { |
| 286 | + const batch = tasks.slice(i, i + batchSize); |
| 287 | +
|
| 288 | + // Process the first task in the batch serially |
| 289 | + // to make sure the Discord bot will create the categories correctly. |
| 290 | + let firstTaskResult: { |
| 291 | + task: ParsedTask; |
| 292 | + taskId: ReturnType<typeof makeId>; |
| 293 | + } | null = null; |
| 294 | + if (batch.length > 0) { |
| 295 | + const firstTask = batch[0]; |
| 296 | + const r = await this.createTask(this.ctf.id, firstTask); |
| 297 | + const newTask = r?.data?.createTask?.task; |
| 298 | + if (newTask) { |
| 299 | + firstTaskResult = { task: firstTask, taskId: makeId(newTask.id) }; |
| 300 | + } |
| 301 | + } |
| 302 | +
|
| 303 | + // Process the rest of the batch in parallel for task creation |
| 304 | + const remainingTaskResults: Array<{ |
| 305 | + task: ParsedTask; |
| 306 | + taskId: ReturnType<typeof makeId>; |
| 307 | + }> = []; |
| 308 | + if (batch.length > 1) { |
| 309 | + const results = await Promise.all( |
| 310 | + batch.slice(1).map(async (task) => { |
| 311 | + const r = await this.createTask(this.ctf.id, task); |
| 312 | + const newTask = r?.data?.createTask?.task; |
| 313 | + if (newTask) { |
| 314 | + return { task, taskId: makeId(newTask.id) }; |
| 315 | + } |
| 316 | + return null; |
| 317 | + }), |
| 318 | + ); |
| 319 | + remainingTaskResults.push( |
| 320 | + ...results.filter( |
| 321 | + ( |
| 322 | + t, |
| 323 | + ): t is { task: ParsedTask; taskId: ReturnType<typeof makeId> } => |
| 324 | + t != null, |
| 325 | + ), |
| 326 | + ); |
| 327 | + } |
| 328 | +
|
| 329 | + // Now process all tag additions in parallel |
| 330 | + const tagPromises: Promise<any>[] = []; |
| 331 | + if (firstTaskResult) { |
| 332 | + tagPromises.push( |
| 333 | + this.addTagsForTask( |
| 334 | + firstTaskResult.task.tags, |
| 335 | + firstTaskResult.taskId as Id<Task>, |
| 336 | + ), |
| 337 | + ); |
| 338 | + } |
| 339 | + tagPromises.push( |
| 340 | + ...remainingTaskResults.map((result) => |
| 341 | + this.addTagsForTask(result.task.tags, result.taskId as Id<Task>), |
| 342 | + ), |
| 343 | + ); |
| 344 | +
|
| 345 | + if (tagPromises.length > 0) { |
| 346 | + await Promise.all(tagPromises); |
289 | 347 | } |
290 | 348 | } |
291 | 349 | }, |
|
0 commit comments