sharding (blacklists): Blacklist shard support.

Moved the `user_blacklist` and `guild_blacklist` to a client TTL cache.
This commit is contained in:
2021-12-22 13:07:20 +02:00
parent 20697c4823
commit 1c05d7a880
10 changed files with 48 additions and 47 deletions

View File

@@ -82,7 +82,7 @@ class LionModule(Module):
raise SafeCancellation(details="Module '{}' is not ready.".format(self.name)) raise SafeCancellation(details="Module '{}' is not ready.".format(self.name))
# Check global user blacklist # Check global user blacklist
if ctx.author.id in ctx.client.objects['blacklisted_users']: if ctx.author.id in ctx.client.user_blacklist():
raise SafeCancellation(details='User is blacklisted.') raise SafeCancellation(details='User is blacklisted.')
if ctx.guild: if ctx.guild:
@@ -91,7 +91,7 @@ class LionModule(Module):
raise SafeCancellation(details='Command channel is no longer reachable.') raise SafeCancellation(details='Command channel is no longer reachable.')
# Check global guild blacklist # Check global guild blacklist
if ctx.guild.id in ctx.client.objects['blacklisted_guilds']: if ctx.guild.id in ctx.client.guild_blacklist():
raise SafeCancellation(details='Guild is blacklisted.') raise SafeCancellation(details='Guild is blacklisted.')
# Check guild's own member blacklist # Check guild's own member blacklist

View File

@@ -1,9 +1,8 @@
""" """
Guild, user, and member blacklists. Guild, user, and member blacklists.
NOTE: The pre-loading methods are not shard-optimised.
""" """
from collections import defaultdict from collections import defaultdict
import cachetools.func
from data import tables from data import tables
from meta import client from meta import client
@@ -11,32 +10,22 @@ from meta import client
from .module import module from .module import module
@module.init_task @cachetools.func.ttl_cache(ttl=300)
def load_guild_blacklist(client): def guild_blacklist():
""" """
Load the blacklisted guilds. Get the guild blacklist
""" """
rows = tables.global_guild_blacklist.select_where() rows = tables.global_guild_blacklist.select_where()
client.objects['blacklisted_guilds'] = set(row['guildid'] for row in rows) return set(row['guildid'] for row in rows)
if rows:
client.log(
"Loaded {} blacklisted guilds.".format(len(rows)),
context="GUILD_BLACKLIST"
)
@module.init_task @cachetools.func.ttl_cache(ttl=300)
def load_user_blacklist(client): def user_blacklist():
""" """
Load the blacklisted users. Get the global user blacklist.
""" """
rows = tables.global_user_blacklist.select_where() rows = tables.global_user_blacklist.select_where()
client.objects['blacklisted_users'] = set(row['userid'] for row in rows) return set(row['userid'] for row in rows)
if rows:
client.log(
"Loaded {} globally blacklisted users.".format(len(rows)),
context="USER_BLACKLIST"
)
@module.init_task @module.init_task
@@ -62,18 +51,20 @@ def load_ignored_members(client):
) )
@module.init_task
def attach_client_blacklists(client):
client.guild_blacklist = guild_blacklist
client.user_blacklist = user_blacklist
@module.launch_task @module.launch_task
async def leave_blacklisted_guilds(client): async def leave_blacklisted_guilds(client):
""" """
Launch task to leave any blacklisted guilds we are in. Launch task to leave any blacklisted guilds we are in.
Assumes that the blacklisted guild list has been initialised.
""" """
# Cache to avoic repeated lookups
blacklisted = client.objects['blacklisted_guilds']
to_leave = [ to_leave = [
guild for guild in client.guilds guild for guild in client.guilds
if guild.id in blacklisted if guild.id in guild_blacklist()
] ]
for guild in to_leave: for guild in to_leave:
@@ -92,7 +83,8 @@ async def check_guild_blacklist(client, guild):
Guild join event handler to check whether the guild is blacklisted. Guild join event handler to check whether the guild is blacklisted.
If so, leaves the guild. If so, leaves the guild.
""" """
if guild.id in client.objects['blacklisted_guilds']: # First refresh the blacklist cache
if guild.id in guild_blacklist():
await guild.leave() await guild.leave()
client.log( client.log(
"Automatically left blacklisted guild '{}' (gid:{}) upon join.".format(guild.name, guild.id), "Automatically left blacklisted guild '{}' (gid:{}) upon join.".format(guild.name, guild.id),

View File

@@ -43,7 +43,7 @@ async def cmd_topcoin(ctx):
# Fetch the leaderboard # Fetch the leaderboard
exclude = set(m.id for m in ctx.guild_settings.unranked_roles.members) exclude = set(m.id for m in ctx.guild_settings.unranked_roles.members)
exclude.update(ctx.client.objects['blacklisted_users']) exclude.update(ctx.client.user_blacklist())
exclude.update(ctx.client.objects['ignored_members'][ctx.guild.id]) exclude.update(ctx.client.objects['ignored_members'][ctx.guild.id])
args = { args = {

View File

@@ -134,7 +134,7 @@ class Reminder:
""" """
Execute the reminder. Execute the reminder.
""" """
if self.data.userid in client.objects['blacklisted_users']: if self.data.userid in client.user_blacklist():
self.delete(self.reminderid) self.delete(self.reminderid)
return return

View File

@@ -59,7 +59,7 @@ async def cmd_stats(ctx):
# Leaderboard ranks # Leaderboard ranks
exclude = set(m.id for m in ctx.guild_settings.unranked_roles.members) exclude = set(m.id for m in ctx.guild_settings.unranked_roles.members)
exclude.update(ctx.client.objects['blacklisted_users']) exclude.update(ctx.client.user_blacklist())
exclude.update(ctx.client.objects['ignored_members'][ctx.guild.id]) exclude.update(ctx.client.objects['ignored_members'][ctx.guild.id])
if target.id in exclude: if target.id in exclude:
time_rank = None time_rank = None

View File

@@ -40,7 +40,7 @@ async def cmd_top(ctx):
# Fetch the leaderboard # Fetch the leaderboard
exclude = set(m.id for m in ctx.guild_settings.unranked_roles.members) exclude = set(m.id for m in ctx.guild_settings.unranked_roles.members)
exclude.update(ctx.client.objects['blacklisted_users']) exclude.update(ctx.client.user_blacklist())
exclude.update(ctx.client.objects['ignored_members'][ctx.guild.id]) exclude.update(ctx.client.objects['ignored_members'][ctx.guild.id])
args = { args = {

View File

@@ -298,7 +298,7 @@ async def session_voice_tracker(client, member, before, after):
pending.cancel() pending.cancel()
if after.channel: if after.channel:
blacklist = client.objects['blacklisted_users'] blacklist = client.user_blacklist()
guild_blacklist = client.objects['ignored_members'][guild.id] guild_blacklist = client.objects['ignored_members'][guild.id]
untracked = untracked_channels.get(guild.id).data untracked = untracked_channels.get(guild.id).data
start_session = ( start_session = (

View File

@@ -47,7 +47,7 @@ def _scan(guild):
members = itertools.chain(*channel_members) members = itertools.chain(*channel_members)
# TODO filter out blacklisted users # TODO filter out blacklisted users
blacklist = client.objects['blacklisted_users'] blacklist = client.user_blacklist()
guild_blacklist = client.objects['ignored_members'][guild.id] guild_blacklist = client.objects['ignored_members'][guild.id]
for member in members: for member in members:

View File

@@ -7,6 +7,8 @@ import discord
from cmdClient.checks import is_owner from cmdClient.checks import is_owner
from cmdClient.lib import ResponseTimedOut from cmdClient.lib import ResponseTimedOut
from meta.sharding import sharded
from .module import module from .module import module
@@ -26,14 +28,14 @@ async def cmd_guildblacklist(ctx, flags):
Description: Description:
View, add, or remove guilds from the blacklist. View, add, or remove guilds from the blacklist.
""" """
blacklist = ctx.client.objects['blacklisted_guilds'] blacklist = ctx.client.guild_blacklist()
if ctx.args: if ctx.args:
# guildid parsing # guildid parsing
items = [item.strip() for item in ctx.args.split(',')] items = [item.strip() for item in ctx.args.split(',')]
if any(not item.isdigit() for item in items): if any(not item.isdigit() for item in items):
return await ctx.error_reply( return await ctx.error_reply(
"Please provide guilds as comma seprated guild ids." "Please provide guilds as comma separated guild ids."
) )
guildids = set(int(item) for item in items) guildids = set(int(item) for item in items)
@@ -80,9 +82,18 @@ async def cmd_guildblacklist(ctx, flags):
insert_keys=('guildid', 'ownerid', 'reason') insert_keys=('guildid', 'ownerid', 'reason')
) )
# Check if we are in any of these guilds # Leave freshly blacklisted guilds, accounting for shards
to_leave = (ctx.client.get_guild(guildid) for guildid in to_add) to_leave = []
to_leave = [guild for guild in to_leave if guild is not None] for guildid in to_add:
guild = ctx.client.get_guild(guildid)
if not guild and sharded:
try:
guild = await ctx.client.fetch_guild(guildid)
except discord.HTTPException:
pass
if guild:
to_leave.append(guild)
for guild in to_leave: for guild in to_leave:
await guild.leave() await guild.leave()
@@ -102,9 +113,8 @@ async def cmd_guildblacklist(ctx, flags):
) )
# Refresh the cached blacklist after modification # Refresh the cached blacklist after modification
ctx.client.objects['blacklisted_guilds'] = set( ctx.client.guild_blacklist.cache_clear()
row['guildid'] for row in ctx.client.data.global_guild_blacklist.select_where() ctx.client.guild_blacklist()
)
else: else:
# Display the current blacklist # Display the current blacklist
# First fetch the full blacklist data # First fetch the full blacklist data
@@ -183,7 +193,7 @@ async def cmd_userblacklist(ctx, flags):
Description: Description:
View, add, or remove users from the blacklist. View, add, or remove users from the blacklist.
""" """
blacklist = ctx.client.objects['blacklisted_users'] blacklist = ctx.client.user_blacklist()
if ctx.args: if ctx.args:
# userid parsing # userid parsing
@@ -245,9 +255,8 @@ async def cmd_userblacklist(ctx, flags):
) )
# Refresh the cached blacklist after modification # Refresh the cached blacklist after modification
ctx.client.objects['blacklisted_users'] = set( ctx.client.user_blacklist.cache_clear()
row['userid'] for row in ctx.client.data.global_user_blacklist.select_where() ctx.client.user_blacklist()
)
else: else:
# Display the current blacklist # Display the current blacklist
# First fetch the full blacklist data # First fetch the full blacklist data

View File

@@ -170,7 +170,7 @@ async def workout_voice_tracker(client, member, before, after):
if member.bot: if member.bot:
return return
if member.id in client.objects['blacklisted_users']: if member.id in client.user_blacklist():
return return
if member.id in client.objects['ignored_members'][member.guild.id]: if member.id in client.objects['ignored_members'][member.guild.id]:
return return