Skip to content

Job doesn't get removed from its queue #873

@mr4pson

Description

@mr4pson

I userd bee-queue for NestJS app. I created @Injectable BeeQueueService to use it accross microservices and registrated queues there.

@Injectable()
export class BeeQueueService {
  public readonly queue: { [key: string]: BeeQueue } = {};
  constructor(private readonly envConfigService: EnvConfigService) {
    this.queue = {
      [EnergyOpsManagerQueue.ENERGY_MANAGEMENT]: new BeeQueue(
        EnergyOpsManagerQueue.ENERGY_MANAGEMENT,
        {
          prefix: 'bq',
          redis: {
            host: this.envConfigService.getValue<string>(EnvVarName.REDIS_HOST),
            port: this.envConfigService.getValue<string>(EnvVarName.REDIS_PORT),
            password: this.envConfigService.getValue<string>(
              EnvVarName.REDIS_PASS,
            ),
            db: 0,
            options: {},
          },
          isWorker: true,
          activateDelayedJobs: true,
          removeOnSuccess: true,
          removeOnFailure: true,
          autoConnect: true,
        },
      ),
    }
  }
  public getQueue(queueName: EnergyOpsManagerQueue | TaskOpsBullQueue | RegistrateOpsBullQueue) {
    return this.queue[queueName];
  }

  public async addJob(
    queue: BeeQueue,
    data: any,
    delay: number,
    jobId?: string,
  ) {
    const date = new Date();
    date.setSeconds(date.getSeconds() + delay / 1000);

    return await queue
      .createJob(data)
      .setId(jobId)
      .delayUntil(date)
      .retries(3)
      .save();
  }

  public async removeJob(queue: BeeQueue, jobId?: string) {
    return await queue.removeJob(jobId);
  }

  public async getJob(queue: BeeQueue, jobId: string) {
    return await queue.getJob(jobId);
  }
}

Also I created bee-queue processor for a specific microservice to handle tasks asynchronously(added timeouts to prevent jobs waiting)

@Injectable()
export class BeeQueueProcessor {
  public readonly queue: { [key: string]: BeeQueue } = {};
  constructor(
    private readonly envConfigService: EnvConfigService,
    private updateEnergyService: UpdateEnergyService,
    @Inject(MicroServiceName.SOCKET_GATEWAY)
    private readonly socketGatewayServiceClient: ClientProxy,
    private energyManagementProducerService: EnergyManagementProducerService,
    private readonly dataAdapterService: DataAdapterService,
    private readonly beeQueueService: BeeQueueService,
  ) {
    this.queue = {
      [EnergyOpsManagerQueue.ENERGY_MANAGEMENT]: new BeeQueue(
        EnergyOpsManagerQueue.ENERGY_MANAGEMENT,
        {
          prefix: 'bq',
          redis: {
            host: this.envConfigService.getValue<string>(EnvVarName.REDIS_HOST),
            port: this.envConfigService.getValue<string>(EnvVarName.REDIS_PORT),
            password: this.envConfigService.getValue<string>(
              EnvVarName.REDIS_PASS,
            ),
            db: 0,
            options: {},
          },
          isWorker: true,
          activateDelayedJobs: true,
          removeOnSuccess: true,
          removeOnFailure: true,
          autoConnect: true,
        },
      ),
    };

    this.queue[EnergyOpsManagerQueue.ENERGY_MANAGEMENT].process(
      async (job, done) => {
        setTimeout(async () => {
          const updatedUser = await this.updateEnergyService.updateEnergy(job);

          setTimeout(async () => {
            await this.energyManagementProducerService.checkAndUpdateEnergy(
              updatedUser,
            );

            // console.log(
            //   'job processed: ',
            //   job.id,
            //   'energy:',
            //   job.data.currentEnergy,
            //   'job completed at: ',
            //   moment(new Date()).format('hh:mm:ss'),
            // );

            this.socketGatewayServiceClient
              .send(EnergyMsgPattern.UPDATE_CLIENT_ENERGY, {
                currentEnergy: updatedUser?.currentEnergy,
                tokenBalance: updatedUser?.tokenBalance,
                userId: job.data.tgUserId,
              })
              .subscribe();
          }, 700);
        }, 300);

        return done(null);
      },
    );
  }
}

Then I need to remove Job from queue

// Inside one of my microservices I invoke removeJob By Id method which should remove job from the queue
await this.energyManagementProducerService.removeJobByTgUserId(tgUserId);

// Method checkAndUpdateEnergy checks if job exists along with other conditions and if there is no job in queue adds it.
@Injectable()
class EnergyManagementProducerService {
  constructor(private readonly beeQueueService: BeeQueueService) {}

  async checkAndUpdateEnergy(user: UserDocument) {
    try {
      const energyLevel =
        user.energyLevel as unknown as EnergyLevelConfigDocument;
      const queue = this.beeQueueService.getQueue(
        EnergyOpsManagerQueue.ENERGY_MANAGEMENT,
      );
      const curJob = await this.beeQueueService.getJob(
        queue,
        user.tgUserId.toString(),
      );

      console.log(user.currentEnergy, energyLevel.value, curJob?.id);

      if (user.currentEnergy >= energyLevel.value || curJob) return;

      const delayNumber = (3600 * 1000) / energyLevel.value;

      // console.log(
      //   'job attached at: ',
      //   moment(new Date()).format('hh:mm:ss'),
      //   'delay: ',
      //   delayNumber,
      //   'energyLevel: ',
      //   energyLevel.levelName,
      //   energyLevel.value,
      // );

      await this.beeQueueService.addJob(
        queue,
        user,
        Math.round(delayNumber),
        user.tgUserId.toString(),
      );
    } catch (error) {
      console.log(error);
    }
  }

  async removeJobByTgUserId(tgUserId: number) {
    const queue = this.beeQueueService.getQueue(
      EnergyOpsManagerQueue.ENERGY_MANAGEMENT,
    );
    return await this.beeQueueService.removeJob(queue, tgUserId.toString());
  }
}

In redis the Job has been removed and in logs I still get the removed job

console.log(25 30 386112959)

I would be really grateful if you fix that issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions