diff options
author | 2021-01-18 16:12:03 -0800 | |
---|---|---|
committer | 2021-01-18 16:12:03 -0800 | |
commit | f444864473931463199916bfa587216b75caf578 (patch) | |
tree | dd5effeaa06b5f02af4348dfbdc9c5e3aa980545 | |
parent | Merge PR #1289 - add branding manager (diff) |
Sync: chunk user requests
The site can't handle huge syncs. Even a bulk patch of 10k users will
crash the service. Chunk the requests into groups of 1000 users and
await them sequentially. Testing showed that concurrent requests
are not scalable and would also crash the service.
-rw-r--r-- | bot/exts/backend/sync/_syncers.py | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/bot/exts/backend/sync/_syncers.py b/bot/exts/backend/sync/_syncers.py index 2eb9f9971..c9f2d2da8 100644 --- a/bot/exts/backend/sync/_syncers.py +++ b/bot/exts/backend/sync/_syncers.py @@ -5,12 +5,15 @@ from collections import namedtuple from discord import Guild from discord.ext.commands import Context +from more_itertools import chunked import bot from bot.api import ResponseCodeError log = logging.getLogger(__name__) +CHUNK_SIZE = 1000 + # These objects are declared as namedtuples because tuples are hashable, # something that we make use of when diffing site roles against guild roles. _Role = namedtuple('Role', ('id', 'name', 'colour', 'permissions', 'position')) @@ -207,10 +210,13 @@ class UserSyncer(Syncer): @staticmethod async def _sync(diff: _Diff) -> None: """Synchronise the database with the user cache of `guild`.""" + # Using asyncio.gather would still consume too many resources on the site. log.trace("Syncing created users...") if diff.created: - await bot.instance.api_client.post("bot/users", json=diff.created) + for chunk in chunked(diff.created, CHUNK_SIZE): + await bot.instance.api_client.post("bot/users", json=chunk) log.trace("Syncing updated users...") if diff.updated: - await bot.instance.api_client.patch("bot/users/bulk_patch", json=diff.updated) + for chunk in chunked(diff.updated, CHUNK_SIZE): + await bot.instance.api_client.patch("bot/users/bulk_patch", json=chunk) |