فهرست منبع

refactor: optimize importExcelTags method for concurrent processing and improved error handling

Dave 3 هفته پیش
والد
کامیت
cfead55d98
1فایلهای تغییر یافته به همراه75 افزوده شده و 57 حذف شده
  1. 75 57
      apps/box-mgnt-api/src/mgnt-backend/feature/video-media/video-media.service.ts

+ 75 - 57
apps/box-mgnt-api/src/mgnt-backend/feature/video-media/video-media.service.ts

@@ -435,70 +435,88 @@ export class VideoMediaService {
 
     let updated = 0;
 
-    for (let i = 0; i < candidates.length; i += 1) {
-      const row = candidates[i];
-      if (i % 100 === 0) {
-        const start = i + 1;
-        const end = Math.min(i + 100, candidates.length);
-        this.logger.log(
-          `[importExcelTags] processing ${start} to ${end} of ${candidates.length}`,
-        );
-      }
-      try {
-        const existing = await this.prisma.videoMedia.findUnique({
-          where: { id: row.id },
-          select: { secondTags: true },
-        });
+    const totalCandidates = candidates.length;
+    const concurrency = 5;
+    let cursor = 0;
+    let nextLogStart = 1;
+
+    const worker = async () => {
+      while (true) {
+        const index = cursor++;
+        if (index >= totalCandidates) break;
+
+        if (index + 1 === nextLogStart) {
+          const end = Math.min(nextLogStart + 99, totalCandidates);
+          process.stdout.write(
+            `[importExcelTags] processing ${nextLogStart} to ${end} of ${totalCandidates}\n`,
+          );
+          nextLogStart += 100;
+        }
+
+        const row = candidates[index];
+
+        try {
+          const existing = await this.prisma.videoMedia.findUnique({
+            where: { id: row.id },
+            select: { secondTags: true },
+          });
+
+          if (!existing) {
+            errors.push({
+              rowNumber: row.rowNumber,
+              idRaw: row.idRaw,
+              reason: 'video not found',
+            });
+            continue;
+          }
+
+          const mergedSecondTags = this.mergeAppendUnique(
+            existing.secondTags ?? [],
+            row.tags,
+          );
+
+          const vTags = row.tags
+            .map((name) => tagMap.get(name))
+            .filter(Boolean)
+            .map((tag) => ({
+              tagId: tag!.id,
+              tagName: tag!.name,
+            }));
+
+          const editedAt = BigInt(Math.floor(Date.now() / 1000));
+          const updatedAt = new Date();
+          const data: Record<string, any> = {
+            tags: { set: row.tags },
+            secondTags: { set: mergedSecondTags },
+            editedAt,
+            updatedAt,
+          };
+
+          if (vTags.length > 0) {
+            data.vTags = { set: vTags };
+          }
 
-        if (!existing) {
+          await this.prisma.videoMedia.update({
+            where: { id: row.id },
+            data,
+          });
+
+          updated += 1;
+        } catch (error: any) {
           errors.push({
             rowNumber: row.rowNumber,
             idRaw: row.idRaw,
-            reason: 'video not found',
+            reason: error?.message ?? String(error),
           });
-          continue;
-        }
-
-        const mergedSecondTags = this.mergeAppendUnique(
-          existing.secondTags ?? [],
-          row.tags,
-        );
-
-        const vTags = row.tags
-          .map((name) => tagMap.get(name))
-          .filter(Boolean)
-          .map((tag) => ({
-            tagId: tag!.id,
-            tagName: tag!.name,
-          }));
-
-        const editedAt = BigInt(Math.floor(Date.now() / 1000));
-        const updatedAt = new Date();
-        const data: Record<string, any> = {
-          tags: { set: row.tags },
-          secondTags: { set: mergedSecondTags },
-          editedAt,
-          updatedAt,
-        };
-
-        if (vTags.length > 0) {
-          data.vTags = { set: vTags };
         }
-
-        await this.prisma.videoMedia.update({
-          where: { id: row.id },
-          data,
-        });
-
-        updated += 1;
-      } catch (error: any) {
-        errors.push({
-          rowNumber: row.rowNumber,
-          idRaw: row.idRaw,
-          reason: error?.message ?? String(error),
-        });
       }
-    }
+    };
+
+    const workers = Array.from(
+      { length: Math.min(concurrency, totalCandidates) },
+      () => worker(),
+    );
+    await Promise.all(workers);
 
     return {
       totalRows: rows.length,