Utilizing BullMQ in Combination with NestJS for Queue Name Management

Currently, I am in the process of developing an application with BullMQ and NestJS. Everything seems to be working smoothly, but there is a particular issue that is bothering me.

Whenever I register a new queue within my application, I typically follow this approach:


    @Module({
       imports: [             
             BullModule.registerQueueAsync({
              name: 'email-queue',
           }),
      ],
      controllers: [EmailController],
      providers: [ ],
    })


Subsequently, when utilizing it within a NestJS service, my code would look something like this:


@Injectable()
export class WhatsappQueueService {
  constructor(
    @InjectQueue('email-queue') private queue: Queue,
  ) {}

  async addMessage(dtoSendMessage: any) {
    const included = await this.queue.add(
      'send-message',
      dtoSendMessage,
    );
    return included;
  }

}

The dilemma arises when I attempt to create a constant with the value 'email-queue', export it from the service, and incorporate it into the Module definition. This way, manual management of queue names can be avoided.

However, upon using the constant, an error is triggered indicating that NestJS is unable to locate the Queue. I suspect this issue is related to the @InjectQueue() decorator.

Is there a means by which constants can be utilized for naming queues?

Answer №1

Absolutely, constants can be utilized

src/queue/constants/queue.constants.ts

export const QUEUE_NAME = 'add-email-vectors-queue';
export const QUEUE_PROCESS = 'save';

export const EMAIL_CACHE_QUEUE_PROCESS = 'email-cache';
export const EMAIL_CACHE_QUEUE_NAME = 'email-cache-queue';
 BullModule.registerQueue({
      name: QUEUE_NAME,
      defaultJobOptions: {
        delay: 1000,
        removeOnComplete: true,
        removeOnFail: true,
        attempts: 3,
      },
    }),
import {
  EMAIL_CACHE_QUEUE_NAME,
  EMAIL_CACHE_QUEUE_PROCESS,
} from './constants/queue.constants';

@Processor(EMAIL_CACHE_QUEUE_NAME)
export class EmailCacheQueueProcessService {
  private readonly logger = new Logger(EmailCacheQueueProcessService.name);

  constructor(
    private readonly outlookService: OutlookService,
    private readonly cacheStoreService: CacheStoreService,
  ) {}

  @Process(EMAIL_CACHE_QUEUE_PROCESS)
  async saveEmailsCacheProcess(job: Job) {
    const emails = await this.outlookService.getEmailsForCaching(
      job.data.token,
      1,
      100,
    );

   
    this.logger.log(`Job completed for ${emails.length} emails in ${EMAIL_CACHE_QUEUE_NAME}`);
  }
}
import { InjectQueue } from '@nestjs/bull';
import { Injectable } from '@nestjs/common';
import { Queue } from 'bull';
import { QUEUE_NAME, QUEUE_PROCESS } from './constants/queue.constants';

@Injectable()
export class QueueService {
  constructor(
    @InjectQueue(QUEUE_NAME)
    private queue: Queue,
  ) {}

  /**
   * @param text email body and the id of the email
   * @param userId user id of the database
   * @description Save emails to vector database from queue
  */
  async saveVectorsFromQueue(
    text: { text: string; id: string }[],
    userId: string,
  ) {
    await this.queue.add(QUEUE_PROCESS, {
      text,
      userId,
    });

    console.log('Job added to queue');
  }
}

Utilizing constants is recommended for naming queues.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Define the data type for the toObject function's return value

Is it possible to define the return type of the toObject method in Mongoose? When working with generics, you can set properties of a Document object returned from a Mongoose query. However, accessing getters and setters on these objects triggers various v ...

HackerRank Challenge: Strategies for Efficiently Solving Minimum Swaps 2

In this challenge, the goal is to determine the minimum number of swaps needed to arrange an array of disordered consecutive digits in ascending order. My code successfully handles most of the tests, but I'm encountering timeout errors with four speci ...

Expecting commitment on the horizon with the utilization of async/await in a TypeScript

Every time I use the loadhtml method within show function, I receive a pending promise. Is there a way to obtain the value without needing a callback function? The code snippet is provided below for reference. async loadhtml(url: string) { ...

Revamping the website to become a Progressive Web App

I am in the process of transforming my website into a Progressive Web App (PWA) and have made some updates to my code to facilitate this: index.html <script> if('serviceWorker' in navigator) { navigator.serviceWorker.registe ...

What is the best way to bring a nested object to the top level without deleting the original top level

Imagine having the following dataset: data = [{ "_id" : "2fApaxgiPx38kpDLA", "profile" : { "name" : "Karina 1", "avatar" : "avatar1.jpg", "bio" ...

Can someone please explain the result of console.log(error) and how can I convert it into a string?

Within a Node.js project that utilizes Typescript and is aimed at ES2020 compatibility, I have implemented a custom Error class in the following manner: class InvalidParamsError extends Error { } try { throw new InvalidParamsError(); } catch (error) { ...

What could be the reason for my function not being executed in this particular scenario with my calculator HTML code?

Memory = "0"; Current = "0"; Operation = 0; MAXLENGTH = 30; alert("yea"); function AddDigit(digit) { alert("yea"); if (Current.length > MAXLENGTH) { Current = "Aargh! Too long"; } else { if (eval(Current) == 0) { Current = dig; ...

My form does not receive the Bootstrap classes when using the jQuery script

**Why isn't my jQuery script coloring the rows as expected when certain conditions are met (I italicized the specific part of the code)?** Here is the HTML CODE for the POLL: <form id="pollForm" class="mb-4"> <d ...

reveal concealed section and seamlessly glide to specified location inside the secret compartment

I have implemented a feature on my website where hidden divs are revealed one at a time, with the screen scrolling to display each specific div. While this code functions well, I am now looking to enhance it by opening the hidden div and smoothly scrolling ...

Submitting data twice through AJAX POST requests

Using a PHP file called via AJAX to insert data into MySQL. Prior to the insert statement, the PHP code runs a select query to check for duplicate records and then proceeds with the insert statement. Problem: When calling the PHP file from AJAX, it gets ...

Adding fields from one collection to another collection in MongoDB based on specific conditions for a considerable amount of data

I encountered a situation where I constantly need to update a large number of collections. Here are the collections: coll1 { "identification_id" : String, "name" : String, "mobile_number" : Number, "location" : String, "user_properties" : [Mixe ...

Components in Angular modules that are loaded lazily with identical names

I have developed an Angular application with multiple lazy-loaded modules. Each of these modules contains different components that are conceptually similar but vary in content. For example, each module may have its own "home" component. Is it advisable t ...

Even though I have the image button's ID, I am unable to successfully click on it

I am facing an issue where I can't seem to click on an image button even though I know its ID: driver.findElement(By.id("its Id")).click() Unfortunately, I cannot provide the website link as it is not a public website. However, I have pasted the HTM ...

What is the best way to configure the default entry point for a package.json file in a React

I'm having trouble with the default export in my package.json file. when I try to import: import { Component } from 'packagename/'; // size 22kb or import { Component } from 'packagename/dist' // size 22kb; but import { Component ...

Navigate to a new page on button click using Row with Tanstack / React-Table and Typescript (2339)

Encountering a linting error when attempting to navigate to a new route by clicking on a table row. The functionality is working but how can I resolve this issue? It's showing an error message stating "The property "id" for type TData does not exist." ...

Trouble setting custom attribute tags in Ionic 4

Trying to apply custom attributes within a ngFor loop is proving challenging for me. <ng-container *ngFor="let a of this.current_items?.areas; let i = index"> ... I've made several attempts: <div class="productBatchArea" custom-data=&apo ...

Is there a way to navigate to the home page using a PNG icon without refreshing the page when clicked on, while also utilizing NavLink with a route of '/'?

Here's the code I'm working with: <div key="1" className="menu-item"> <NavLink to="/"> <span className="icon-home3" />&nbsp; Home </NavLink> </div> The Home button functions ...

Incorporating URL addresses and pagination features using React.Js and Material-UI components

I have a functional component-page on my website, where I display a table that fetches data from an API. To improve user experience, I implemented pagination using the Material-UI library. While the pagination functionality works fine in updating the table ...

Error: Attempting to use Moment with Bootstrap Date Time Picker results in TypeError, as Object(...) is not recognized as

Let me show you the code for my picker in a simple way: import {moment} from 'moment'; const datePicker = () => { $('.datetimepicker').datetimepicker({ format: 'LT', locale: 'PT-BR', icons: { ...

Tips for navigating through elements generated with ng-repeat as I scroll

There is a list generated using ng-repeat along with two buttons for moving up or down. Users have the option to select any item from the list and utilize the buttons to navigate through it. However, when I lower the selected item using the "go down" butt ...