如何检查redis队列中作业的状态?

nnt7mjpx  于 2021-06-09  发布在  Redis
关注(0)|答案(0)|浏览(250)

在nodejs应用程序中,我有一个可以发布图像文件的路由。然后将图像文件上载到临时文件夹,并使用bull将新作业添加到redis队列。队列的使用者将图像调整为标准web大小的图像(缩略图),提取元数据并将路径和一些信息添加到我的mongodb中。
我的问题是如何通知前端应用程序的用户文件已经上传、调整大小等,然后添加到数据库中?一旦上传,我的api就会返回一些关于添加到bull队列中的每个作业的信息。最好的方法是每隔一秒左右查询一次api来检查队列项的状态吗?
在我的本地机器上,每项作业大约需要10秒,这就是我使用队列来避免请求超时的原因。
一些代码。。。

@ApiConsumes('multipart/form-data')
  @Post(':id/upload')
  @UseInterceptors(
    FilesInterceptor('files', 100, {
      limits: {
        fileSize: PhotosController.maxFileSize // A 40MB limit per file
      },
      storage: multer.diskStorage({
        destination: PhotosController.fileDestination,
        filename: (req, file, callback) => {
          const name = PhotosController.createFileName(file);
          callback(null, name);
        }
      }),
      fileFilter: (req, file, callback) => {
        const allowedFileTypes = ['.png', '.jpg', '.jpeg'];
        const allowedMimetypes = ['image/jpeg', 'image/png'];
        const fileExtension = path.extname(file.originalname).toLowerCase();
        if (!allowedFileTypes.includes(fileExtension)) {
          callback(new Error(`Incorrect file type: ${fileExtension}`), false);
        }
        if (!allowedMimetypes.includes(file.mimetype)) {
          callback(
            new Error(`Incorrect file mimetype: ${file.mimetype}`),
            false
          );
        }
        callback(null, true);
      }
    })
  )
  public uploadFile(
    @UploadedFiles() files: any[],
    @Param('id') _id: string | ObjectId
  ) {
    if (!files) {
      throw new BadRequestException('No files uploaded.');
    }
    files.map(file => {
      file['albumID'] = _id;
      return file;
    });
    return this.filesService.addToFileUploadQueue(files);
  }

文件服务:

@Injectable()
export class FilesService {
  constructor(@InjectQueue('Main') private readonly queue: Queue) {}

  public addToFileUploadQueue(files): Promise<Bull.Job[]> {
    const jobs = [];
    for (const file of files) {
      jobs.push(this.queue.add('resize', file));
    }
    return Promise.all(jobs);
  }
}

最后,工作消费者:

@Process('resize')
  public async handleTranscode(job: Job) {
    try {
      const file = job.data;

      const ext = file.originalname.split('.')[1];

      const thumbName = [
        `${file.filename.split('.')[0]}_thumb`,
        file.filename.split('.')[1]
      ].join('.');

      const fileNameSansExt = file.filename.split('.')[0];

      return await forkJoin([
        // Create standard image
        this.image.resizeToFile(
          file.path,
          `${this.dest}\\${file.albumID}\\`,
          file.filename,
          1920,
          1920,
          { withoutEnlargement: true, fit: 'inside' }
        ),
        // Create thumbnail image
        this.image.resizeToFile(
          file.path,
          `${this.dest}\\${file.albumID}\\`,
          thumbName,
          50,
          50,
          {
            withoutEnlargement: true,
            fit: 'inside'
          }
        ),
        // Extract the metadata from the image
        this.image.getMeta(file.path)
      ])
        .pipe(
          switchMap(([largeImage, thumb, meta]) => {
            // Delete the temporary file
            return this.ft
              .delete(file.path)
              .pipe(map(() => [largeImage, thumb, meta]));
          }),
          switchMap(([largeImage, thumb, meta]) => {
            // Create the standard photo document and insert it into the database.
            const photoDocument = {
              _id: new ObjectId(),
              mimetype: file.mimetype,
              path: `\\${file.albumID}\\${fileNameSansExt}.${ext}`,
              thumb: `\\${file.albumID}\\${fileNameSansExt}_thumb.${ext}`,
              imageDimensions: {
                width: largeImage.width,
                height: largeImage.height
              },
              thumbDimensions: {
                width: thumb.width,
                height: thumb.height
              },
              encoding: file.encoding,
              size: largeImage.size,
              thumbSize: thumb.size,
              meta: meta
            };
            return this.photosService
              .updateAlbum(
                file.albumID,
                { $push: { photos: photoDocument } },
                { upsert: true }
              )
              .pipe(map(dbResult => ({ largeImage, thumb, meta, dbResult })));
          })
        )
        .pipe(
          tap(result => {
            if (process.env.NODE_ENV === 'development') {
              console.log(result);
            }
          })
        )
        .toPromise();
    } catch ($e) {
      console.log($e);
    }
  }

如果这个问题涉及面太广,我很抱歉。我只是想听听你的想法。
注意:这是对api使用nestjs,对ui使用react,对队列使用bull和redis。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题