projectdiscovery / notify

Notify is a Go-based assistance package that enables you to stream the output of several tools (or read from a file) and publish it to a variety of supported platforms.

Home Page:https://projectdiscovery.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

-rate-limit=n allows an initial burst of n requests then slows to 1/sec

justinsteven opened this issue · comments

Notify version:

% ./notify -version

             __  _ ___
  ___  ___  / /_(_) _/_ __
 / _ \/ _ \/ __/ / _/ // /
/_//_/\___/\__/_/_/ \_, / v1.0.1
                   /___/

                projectdiscovery.io

Use with caution. You are responsible for your actions
Developers assume no liability and are not responsible for any misuse or damage.
[INF] Current Version: 1.0.1

Current Behavior:

Applying -rate-limit=n allows an initial burst of n notifications (at least as quick of a burst as the notification provider allows :^) ) and then immediately slows to one notification per second.

Demo:

% yes | head -n30 | time ./notify -rate-limit=10

             __  _ ___
  ___  ___  / /_(_) _/_ __
 / _ \/ _ \/ __/ / _/ // /
/_//_/\___/\__/_/_/ \_, / v1.0.1
                   /___/

                projectdiscovery.io

Use with caution. You are responsible for your actions
Developers assume no liability and are not responsible for any misuse or damage.
Using default provider config: /home/justin/.config/notify/provider-config.yaml
y
y
y
[... SNIP ...]
y
y
./notify -rate-limit=10  0.10s user 0.07s system 0% cpu 20.266 total

Sending 30 notifications with a -rate-limit of 10 took 20 seconds. This works out to a negligible amount of time for the first 10 notifications, and then approximately one per second for the remaining 20 notifications. I would have expected it to complete in closer to 3 seconds.

Expected Behavior:

--rate-limit=n should allow notifications to consistently be sent at a maximum of n notifications per second, with any limits beyond that being due to the responsiveness of the notification provider.

Steps To Reproduce:

Anything else:

Thanks @LuitelSamikshya ! It's still doing it. Maybe I just don't understand leaky bucket rate limiting :(

Demo:

% time yes | head -n30 | pv -q -L4 | notify -rl 2 >/dev/null

             __  _ ___
  ___  ___  / /_(_) _/_ __
 / _ \/ _ \/ __/ / _/ // /
/_//_/\___/\__/_/_/ \_, / v1.0.2-dev
                   /___/

                projectdiscovery.io

Use with caution. You are responsible for your actions
Developers assume no liability and are not responsible for any misuse or damage.
Using default provider config: /home/justin/.config/notify/provider-config.yaml
[ERR] failed to send discord notification for id: discord : failed to send discord notification: response status code 429 Too Many Requests
[ERR] failed to send discord notification for id: discord : failed to send discord notification: response status code 429 Too Many Requests
[ERR] failed to send discord notification for id: discord : failed to send discord notification: response status code 429 Too Many Requests
[ERR] failed to send discord notification for id: discord : failed to send discord notification: response status code 429 Too Many Requests
yes  0.00s user 0.00s system 59% cpu 0.006 total
head -n30  0.00s user 0.00s system 83% cpu 0.004 total
pv -q -L4  0.00s user 0.01s system 0% cpu 14.974 total
notify -rl 2 > /dev/null  0.09s user 0.07s system 0% cpu 28.864 total

(Hah, I'm still hitting the Discord rate limit at an effective rate of what I will show to be about one line per second. Oh well...)

yes | head -n30 gives us 30 lines of "y". pv rate limits it to 4 bytes (2 lines) per second. notify has a rate limit of 2 per second. I would expect that notify would be able to roughly keep up with the input.

time tells us that pv takes 15 seconds to run. 30 lines at 2 lines per second. That sounds right.

Why does notify take 28 seconds? Shouldn't its rate limit be able to keep up with the input?
I would understand if notify took 2 or 4 more seconds than pv. but not almost twice as long. It's as though notify hits the rate limit and from then on, given constant input, sends no more than 1 line per second.

Is that what leaky bucket is supposed to do? If so, then things are working as advertised, even if it's not how I thought a rate limit would work, and I need to learn more about rate limits.

Edit: I was running an old build by mistake 🤦‍♂️ the patch is perfect 👍

% time yes | head -n30 | pv -q -L4 | ./notify -rl 2 >/dev/null

             __  _ ___
  ___  ___  / /_(_) _/_ __
 / _ \/ _ \/ __/ / _/ // /
/_//_/\___/\__/_/_/ \_, / v1.0.2-dev
                   /___/

                projectdiscovery.io

Use with caution. You are responsible for your actions
Developers assume no liability and are not responsible for any misuse or damage.
Using default provider config: /home/justin/.config/notify/provider-config.yaml
yes  0.00s user 0.00s system 60% cpu 0.006 total
head -n30  0.00s user 0.00s system 83% cpu 0.004 total
pv -q -L4  0.01s user 0.01s system 0% cpu 14.974 total
./notify -rl 2 > /dev/null  0.12s user 0.08s system 1% cpu 15.301 total