Manechat / izzy-moonbot

Replacement admin bot for Manechat
https://manechat.net
MIT License
4 stars 4 forks source link

Hitting ratelimits for getting/deleting spam messages #167

Closed CloudburstSys closed 10 months ago

CloudburstSys commented 1 year ago

Izzy sometimes hits ratelimits for deleting messages.

Potential fix: Service which specifically queues message delete requests so that ratelimits aren't hit.

Ixrec commented 1 year ago

To summarize the Discord discussion, we have two relatively small fixes in mind for the spam situation:

If we discover any other ways Izzy can get rate-limited in practice, those would require some other solution. For example, if fifty users spam at once, she'd probably hit limits, but that's probably not a serious concern in practice.

Ixrec commented 1 year ago

Some of my spam tests show rate limit warnings for getting messages, not just for deleting them. I'm not sure what we can do about that.

Ixrec commented 1 year ago

After circling back to this today, thinking about it some more, experimenting in Bot Testing and reading about C# thread stuff, I have arrived at the following conclusions:

We should probably still do the ideas in https://github.com/Manechat/izzy-moonbot/issues/167#issuecomment-1335066966 and https://github.com/Manechat/izzy-moonbot/issues/169 as well, but locking _users ought to be necessary and sufficient to deal with the specific problem of Izzy getting herself rate limited by a relatively small number of incoming events. I don't think we need to defend ourselves against moderators or Discord itself generating too many commands or events (and Izzy already switches to batch logging ModChannel messages during a raid).

Ixrec commented 10 months ago

I made an attempt to either use channel.DeleteMessagesAsync() or avoid GetMessageAsync(), but concluded that these are too difficult or problematic to be worth it.

GetMessageAsync() is necessary because it will always be possible for a spammer to post N messages, have Izzy delete all N of them and post a modchat summary, then an additional few messages from the same spammer to finally reach Izzy, leading to a second round of deletions with a second modchat summary. That second round needs to know that half of what's in the RecentMessages cache has already been deleted, and actually fetching the messages is the only way to be sure they still exist. Since the only bulk fetch method I know of--channel.GetMessagesAsync()--assumes a contiguous range of messages, we can't use that here either.

DeleteMessagesAsync() has a murkier problem: It turns out to be the first use case we've had for a method interacting with Discord that takes another Discord object we need to mock as an argument. Specifically: it doesn't want a list of message ids as I hoped; it wants a list of IMessages. So even if I wrote an Izzy mock for this it would have to involve asking "is this IIzzyMessage a real Discord IMessage or the TestMessage?" at runtime, which is brittle enough I don't believe this is worth it. Not to mention it would be a pain to restructure the deletion loop to group messages by channel.

With those specific changes rejected, it looks like #523 was the last step of this issue after all. Unless we get a real incident of a spammer causing Izzy to go haywire instead of just delete the spam and ping us about it a few times, I don't think there's anything more to be done here.