diff options
author | 2021-05-22 13:17:02 -0700 | |
---|---|---|
committer | 2021-05-22 13:17:02 -0700 | |
commit | e8b110d12e183c4b9ff1fac63bb509d910d0ccd7 (patch) | |
tree | bb0a8eb8aadbc0360626781caac9e5837669e223 | |
parent | Merge pull request #1593 from python-discord/flake-8-isn't-a-task (diff) |
Fix infraction rescheduler breaking with more than 100 in flight reactions
Make sure to only fetch infractions to reschedule by filtering by type and permanent status. We don't reschedule permanents as they will never be automatically expired, so they're a waste and clog to filter out manually. There is a PR for `site` to add the requisite filters (`types` and `permanent`).
We also only reschedule the soonest-expiring infractions, waiting until we've processed all of them before fetching the next batch by ordering them by expiration time.
-rw-r--r-- | bot/exts/moderation/infraction/_scheduler.py | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/bot/exts/moderation/infraction/_scheduler.py b/bot/exts/moderation/infraction/_scheduler.py index 988fb7220..c94874787 100644 --- a/bot/exts/moderation/infraction/_scheduler.py +++ b/bot/exts/moderation/infraction/_scheduler.py @@ -48,11 +48,32 @@ class InfractionScheduler: infractions = await self.bot.api_client.get( 'bot/infractions', - params={'active': 'true'} + params={ + 'active': 'true', + 'ordering': 'expires_at', + 'permanent': 'false', + 'types': ','.join(supported_infractions), + }, ) - for infraction in infractions: - if infraction["expires_at"] is not None and infraction["type"] in supported_infractions: - self.schedule_expiration(infraction) + + to_schedule = [i for i in infractions if not i['id'] in self.scheduler] + + for infraction in to_schedule: + log.trace("Scheduling %r", infraction) + self.schedule_expiration(infraction) + + # Call ourselves again when the last infraction would expire. This will be the "oldest" infraction we've seen + # from the database so far, and new ones are scheduled as part of application. + # We make sure to fire this + if to_schedule: + next_reschedule_point = max( + dateutil.parser.isoparse(infr["expires_at"]).replace(tzinfo=None) for infr in to_schedule + ) + log.trace("Will reschedule remaining infractions at %s", next_reschedule_point) + + self.scheduler.schedule_at(next_reschedule_point, -1, self.reschedule_infractions(supported_infractions)) + + log.trace("Done rescheduling") async def reapply_infraction( self, |