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

bot, rules: fix rate limiting rules without a rate limit #2629

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Exirel
Copy link
Contributor

@Exirel Exirel commented Oct 12, 2024

Description

Fix #2627 by checking if the rate limit is actually set (equal or less than 0s).

I decided to make the at_time parameter mandatory, as it's all internal stuffs and it makes it clearer what time we are comparing it to. That's how I figured out that it was about the repeating call to the same rule for a single trigger: it would check against the same trigger object, but compare it to the latest call to now(). That's why the bug was visible on url rules, and it affected find rules as well.

Checklist

  • I have read CONTRIBUTING.md
  • I can and do license this contribution under the EFLv2
  • No issues are reported by make qa (runs make lint and make test)
  • I have tested the functionality of the things this change touches

@Exirel Exirel added the Bugfix Generally, PRs that reference (and fix) one or more issue(s) label Oct 12, 2024
@Exirel Exirel added this to the 8.0.1 milestone Oct 12, 2024
@Exirel Exirel requested a review from dgw October 12, 2024 13:51
Copy link
Member

@dgw dgw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than a minor style nit, I have nothing to say, really.

Not the end of the world if you don't get around to git commit --amend && git push -f before I come back to merge this (next week? probably) but that one tiny section of code I commented on would be slightly more readable. 😅

sopel/bot.py Show resolved Hide resolved
@@ -594,27 +594,26 @@ def rate_limit_info(
) -> tuple[bool, Optional[str]]:
if trigger.admin or rule.is_unblockable():
return False, None

nick = trigger.nick
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
nick = trigger.nick
nick = trigger.nick

Like that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, like that. I guess it allows you to "put back the deleted line" if you select only the "added" line and edit manually.

All this time and the suggestion UX is still "meh" at best. 🫤

@dgw dgw mentioned this pull request Oct 14, 2024
4 tasks
Copy link
Member

@dgw dgw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I suggested as much as I could relating to the unnecessary *_metrics assignments. GitHub won't let me add a line note to the metrics = global_metrics line, so sorry, you're on your own.

This will not fix errors in mypy 1.12, though. What this code does with channel is incompatible with the AbstractRule interface.

Comment on lines 598 to 603
is_channel = trigger.sender and not trigger.sender.is_nick()
channel = trigger.sender if is_channel else None

at_time = trigger.time

user_metrics = rule.get_user_metrics(trigger.nick)
user_metrics = rule.get_user_metrics(nick)
channel_metrics = rule.get_channel_metrics(channel)
global_metrics = rule.get_global_metrics()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With mypy 1.12.0 (released today), channel_metrics = rule.get_channel_metrics(channel) causes a type-check error at R602 in this patch's version of the file:

sopel/bot.py:604: error: Argument 1 to "get_channel_metrics" of "AbstractRule" has incompatible type "Any | None"; expected "Identifier"  [arg-type]

Since the revised code doesn't use the RuleMetrics objects in this section any more, the block of *_metrics assignments here can be removed.

That won't fix the other problem, though, which is that both rule.is_channel_rate_limited() and rule.get_channel_metrics() expect Identifier and do not accept None.

Comment on lines +601 to 604
user_metrics = rule.get_user_metrics(nick)
channel_metrics = rule.get_channel_metrics(channel)
global_metrics = rule.get_global_metrics()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
user_metrics = rule.get_user_metrics(nick)
channel_metrics = rule.get_channel_metrics(channel)
global_metrics = rule.get_global_metrics()

channel_metrics = rule.get_channel_metrics(channel)
global_metrics = rule.get_global_metrics()

if user_metrics.is_limited(at_time - rule.user_rate_limit):
at_time = trigger.time
if rule.is_user_rate_limited(trigger.nick, at_time):
template = rule.user_rate_template
rate_limit_type = "user"
rate_limit = rule.user_rate_limit
metrics = user_metrics
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
metrics = user_metrics
metrics = rule.get_user_metrics(nick)

channel_metrics = rule.get_channel_metrics(channel)
global_metrics = rule.get_global_metrics()

if user_metrics.is_limited(at_time - rule.user_rate_limit):
at_time = trigger.time
if rule.is_user_rate_limited(trigger.nick, at_time):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if rule.is_user_rate_limited(trigger.nick, at_time):
if rule.is_user_rate_limited(nick, at_time):

Unrelated to the refactor I'm suggesting re: metrics objects; this just doesn't use the local variable for some reason?

template = rule.user_rate_template
rate_limit_type = "user"
rate_limit = rule.user_rate_limit
metrics = user_metrics
elif is_channel and channel_metrics.is_limited(at_time - rule.channel_rate_limit):
elif is_channel and rule.is_channel_rate_limited(channel, at_time):
template = rule.channel_rate_template
rate_limit_type = "channel"
rate_limit = rule.channel_rate_limit
metrics = channel_metrics
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
metrics = channel_metrics
metrics = rule.get_channel_metrics(channel)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bugfix Generally, PRs that reference (and fix) one or more issue(s)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rate limiting can be incorrectly applied to callables with no limit set
2 participants