A workaround for an apparent bug in Discord.Net's
`SocketGuild.DownloadUsersAsync()` method.
Conclusions made while writing and testing this workaround:
* The guilds it hangs on are seemingly random.
* Guild size does not matter.
* If a download hangs, it never recovers within 2 hours, probably more.
* Trying a guild again never works. It just hangs again.
The public instance will be updated with this fix immediately.
This fixes cases in which those with moderator roles are unable
to use mod-only commands as intended.
It also fixes a dangerous bug in which users with the birthday role
assigned to them have unrestricted access to moderator commands.
A better logging implementation is no longer planned for now, as the
current method has proven to be sufficient so far. It may even continue
to be so for a while.
Accidentally rewrote a handful of things while I was at it. The changes are staying.
After a long search, I found that this issue only shows itself if the bot is in several servers, encountering a valid configuration while it has yet to look at more servers (that is, a situation my debug bot is not in). The loop had been quitting halfway through for reasons seemingly beyond any logic or comprehension.
I already had a hunch that the query I wrote earlier was needlessly complex, as one might expect considering it was written during a state of delirium. It was easy to simplify it. I hoped that would be it, but no change occurred. On the contrary, some checks I slipped in there in the meantime were *passing*.
Further and further investigation finally revealed that the exception handler for background services doesn't actually do what it's expected to do. It's been silently dropping the exceptions that EF had been throwing this whole time, telling me quite plainly what the problem was and why it was quitting at a seemingly random spot.
The fix: Turns out the query evaluates during the foreach loop, which conflicts with wanting to do additional queries within it. Throwing a ToList() somewhere in it seems to have solved it.
These last few hours were quite the adventure...
My head hurts. Now I'm off to take a look at the exception handler.
-Remove webhook logging references
--Including config line. Idea is abandoned for now.
-Remove unneeded comments
-Remove diagnostic messages
--Corresponding problems were solved by moving to dedicated hardware
-Update style on all affected files
Fill it quicker when immediately needed, removing the need for a request list and all relating to it in the corresponding background service.
Additionally, updated usings, style, nullables in all affected files.
This staggering was most likely the cause of a major amount of data lost recently, in which certain guilds never had their values updated.
The staggering was meant to attempt to reduce load on a server with limited capabilities, and testing shows that it runs on more capable hardware without this issue when run this way.
Removes some messy code as a result of the old feature's removal.
Additionally, updated code style in ManagerCommands and fixed several nullable issues.
-Removed a number of diagnostic messages
-Removed ConnectionStatus, connection scores, etc.
-Modified work intervals for certain background tasks
-Updated code style
Implemented several workarounds to what appearto be a library bug in
which not all users will be downloaded onto the cache. User cache
checking and downloading is delegated to a new Common method and a
new BackgroundService, respectively.
This is hopefully temporary.
- Manager loop updated to act on dead shards and initialize new ones
- Initialization of new shards is now staggered in case of many shards
- Now using intents
- Adding a delay and a second connection check when downloading guild
members. This has greatly improved stability over the previously
attempted method.
- No longer sends guild counts to external sites until fully connected
The BirthdayBot class has been split up into ShardInstance and
ShardManager. Several other things have been reorganized so that shards
may act independently.
The overall goal of these changes made is to limit failures to sections
that can easily be discarded and replaced.