Discord REST client, cache and #225 settings (server-26#225 S2) #231
@@ -639,7 +639,19 @@ async def guild_snapshot(token_doc: dict, guild_id: str, *, refresh: bool = Fals
|
||||
needed — and ``/guilds/{g}/channels``). ``refresh=True`` skips the cache
|
||||
(a concurrent load is still shared). Never raises for a Discord failure."""
|
||||
guild_id = str(guild_id)
|
||||
key = (str(token_doc.get("token_id")), guild_id, "snapshot")
|
||||
return await access_cache.get_or_load(
|
||||
key, lambda: _load_snapshot(token_doc, guild_id),
|
||||
lambda s: ttl_for(s.status), refresh=refresh)
|
||||
token_id = str(token_doc.get("token_id"))
|
||||
key = (token_id, guild_id, "snapshot")
|
||||
|
||||
async def _load() -> GuildSnapshot:
|
||||
# Fail open on anything else too (a Firestore write inside the
|
||||
# classification, a malformed body): the caller gets UNKNOWN, never
|
||||
# an exception, and a shielded load never dies unretrieved.
|
||||
try:
|
||||
return await _load_snapshot(token_doc, guild_id)
|
||||
except Exception as e:
|
||||
logger.warning(f"Discord snapshot for bot {token_id} in {guild_id} failed: {type(e).__name__}")
|
||||
return GuildSnapshot(token_id=token_id, guild_id=guild_id, status=UNKNOWN,
|
||||
bot_user_id=token_doc.get("bot_user_id"),
|
||||
error=f"check failed ({type(e).__name__})")
|
||||
|
||||
return await access_cache.get_or_load(key, _load, lambda s: ttl_for(s.status), refresh=refresh)
|
||||
|
||||
@@ -334,6 +334,21 @@ async def test_missing_access_alone_never_changes_membership(discord, fs):
|
||||
assert snap.status == rest.UNKNOWN and fs.get("bot_tokens", "t1")["guild_ids"] == [G]
|
||||
|
||||
|
||||
async def test_non_discord_failure_is_unknown_not_raised(discord, fs, monkeypatch):
|
||||
# A Firestore error while classifying (here: dropping membership) must
|
||||
# fail open — S3's start_stream relies on the snapshot never raising.
|
||||
_guild_routes(discord)
|
||||
discord.routes[("GET", f"/guilds/{G}")] = httpx.Response(404, json={"code": 10004})
|
||||
tok = _token_doc(fs)
|
||||
|
||||
async def _boom(*a, **kw):
|
||||
raise RuntimeError("firestore down")
|
||||
monkeypatch.setattr(rest, "_drop_membership", _boom)
|
||||
snap = await rest.guild_snapshot(tok, G)
|
||||
assert snap.status == rest.UNKNOWN and "RuntimeError" in snap.error
|
||||
assert TOKEN not in snap.error
|
||||
|
||||
|
||||
async def test_unknown_result_is_cached_briefly(discord, fs):
|
||||
discord.routes[("GET", f"/guilds/{G}")] = httpx.Response(503)
|
||||
tok = _token_doc(fs)
|
||||
|
||||
Reference in New Issue
Block a user