Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: RateLimitError() not working #2193

Closed
1 task done
wootwoot1234 opened this issue Sep 22, 2023 · 10 comments
Closed
1 task done

[Bug]: RateLimitError() not working #2193

wootwoot1234 opened this issue Sep 22, 2023 · 10 comments

Comments

@wootwoot1234
Copy link

Version

4.11

Platform

NodeJS

What happened?

The rate limiter doesn't move jobs to waiting when the Worker.RateLimitError() error is thrown. Even though the RateLimitError() has been thrown, the jobs move from delayed to active and continues to run jobs.

How to reproduce.

import { Queue, Worker } from "bullmq";
import IORedis from "ioredis";

const connection = new IORedis({
  host: process.env.REDIS_HOST,
  port: Number(process.env.REDIS_PORT),
  password: process.env.REDIS_PASS,
});

const queueName = 'rate-limit-test';
const queue = new Queue(queueName, {connection});

await queue.drain();
await queue.addBulk(
    Array.from({
        length: 2,
    }).map((_, idx) => ({
        name: "test-job",
        data: {
            idx
        },
        opts: {
            delay: idx * 5_000
        }
    }))
);

const worker = new Worker(
    queueName,
    async (job) => {
        console.log(job.data);
        await worker.rateLimit(60 * 1_000);
        throw Worker.RateLimitError();
    },
    // `concurrency` seems to be an issue if set it a bigger value such as 10 in this case
    // then 1st active job remains in active list and continue to retry even if the queue is being rate limited
    // and once the delayed job is time to run, it gets moved to active before getting moved back to waiting list
    // if set = 1, it works as expected
    // which is all active jobs should be moved to waiting list as the queue is rate limited
    { concurrency: 10, connection }
);

Relevant log output

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct
@wootwoot1234 wootwoot1234 added the bug Something isn't working label Sep 22, 2023
@wootwoot1234
Copy link
Author

Another easy way to see the issue is to only add 1 job and look at the logs, you will see that it continues to run the job and throw the Worker. RateLimitError() even though there is a 60-second rate limit set.

@wootwoot1234
Copy link
Author

We created a complete repo here https://github.com/tmhao2005/bullmq-rate-limit

@roggervalf
Copy link
Collaborator

hey @wootwoot1234 from your example I'm seeing that limiter.max option is missing in the worker config as we check if that value is present in order to do a rate limit validation for the next job keys. Seems like in our docs https://docs.bullmq.io/guide/rate-limiting#manual-rate-limit we were missing to add that option as in our test cases https://github.com/taskforcesh/bullmq/blob/master/tests/test_rate_limiter.ts#L360-L363

@wootwoot1234
Copy link
Author

wootwoot1234 commented Sep 23, 2023 via email

@wootwoot1234
Copy link
Author

I've updated my code and the manual rate limiting is working but when the queue is manually rate-limited and delayed jobs should run, the jobs are not moved from delayed to waiting. Instead, they stay in delayed, and then when the manual rate limit is finished, they all go to active. I expect them to go to waiting while the queue is rate-limited. Is this the expected behavior?

@manast
Copy link
Contributor

manast commented Sep 25, 2023

I think it is expected that they go from delayed directly to active. We improved how delayed jobs are handled, so now they do not need to go back to wait and then move to active, they go directly. But this should not affect the rate limiting, is it doing so?

@wootwoot1234
Copy link
Author

wootwoot1234 commented Sep 25, 2023 via email

@roggervalf
Copy link
Collaborator

hey @wootwoot1234, we are actually moving delayed jobs to wait, this is happening in the moveToActive script, but when the queue is rate limited, workers are not going to execute moveToActive, they are going to be in an idle state, then when the queue is not rate limited, workers will call moveToActive, this script promote delayed jobs (move them into wait state), but in the same script later we also move from wait to active, we only move 1 job to active, so the other promoted delayed jobs should be in wait or in prioritized state (if they have priority > 0)

@wootwoot1234
Copy link
Author

wootwoot1234 commented Sep 26, 2023 via email

@roggervalf
Copy link
Collaborator

hey @wootwoot1234, yes, delayed jobs will be moved to wait after those 10 seconds, this is happening because we will use those 10 seconds to postpone any job execution https://github.com/taskforcesh/bullmq/blob/master/src/classes/worker.ts#L486, after that time we will call moveToActive command that it's the one that moves delayed jobs to wait

@roggervalf roggervalf added works as designed and removed bug Something isn't working labels Nov 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants