fix(bot): 🐛 Redis failing to connect in different event loops.

This commit is contained in:
Nyeki.py
2024-10-23 23:33:25 -03:00
parent 7acfb87910
commit c5143de3ba
11 changed files with 133 additions and 90 deletions
+1
View File
@@ -5,6 +5,7 @@ COPY . .
RUN pip install uv RUN pip install uv
RUN uv sync --no-dev RUN uv sync --no-dev
RUN uv add uvloop
ENTRYPOINT [ "/bin/bash" ] ENTRYPOINT [ "/bin/bash" ]
CMD [ "run.sh" ] CMD [ "run.sh" ]
+28 -13
View File
@@ -2,6 +2,8 @@ from typing import Literal
from datetime import datetime, timezone, timedelta from datetime import datetime, timezone, timedelta
import sys
import discord import discord
from discord import abc from discord import abc
from discord.ext import commands from discord.ext import commands
@@ -9,12 +11,17 @@ from discord.ext.commands import errors
from tortoise import expressions, transactions, exceptions as tortoise_exc from tortoise import expressions, transactions, exceptions as tortoise_exc
import redis.asyncio as aredis
import asyncpg.exceptions
from payphone.db import setup, models from payphone.db import setup, models
from payphone.core import constants, exceptions, formatting, help_command, config from payphone.core import constants, exceptions, formatting, help_command, config
from payphone.core.redis import redis
class Payphone(commands.AutoShardedBot): class Payphone(commands.AutoShardedBot):
redis: aredis.Redis
def __init__(self) -> None: def __init__(self) -> None:
intents = discord.Intents.default() intents = discord.Intents.default()
intents.message_content = True intents.message_content = True
@@ -39,13 +46,11 @@ class Payphone(commands.AutoShardedBot):
console. console.
""" """
self.redis = aredis.Redis(host="localhost" if config.IS_DEBUG else "redis")
await setup.init() await setup.init()
await redis.ping() await self.redis.ping()
await redis.delete(
constants.CHANNELS_ONCALL_SET, constants.CHANNELS_SEARCH_QUEUE
)
print(f"Ready! Logged in as {self.user.display_name}.") print(f"Ready! Logged in as {self.user.display_name}.")
@@ -121,7 +126,7 @@ class Payphone(commands.AutoShardedBot):
user_id = user if isinstance(user, int) else user.id user_id = user if isinstance(user, int) else user.id
key = constants.BAN_TEMPLATE % user_id key = constants.BAN_TEMPLATE % user_id
is_banned = await redis.get(key) is_banned = await self.redis.get(key)
if is_banned is not None: if is_banned is not None:
return bool(int(is_banned)) return bool(int(is_banned))
@@ -135,7 +140,7 @@ class Payphone(commands.AutoShardedBot):
), ),
).exists() ).exists()
await redis.set(key, int(is_banned), ex=300) await self.redis.set(key, int(is_banned), ex=300)
return is_banned return is_banned
@@ -203,7 +208,7 @@ class Payphone(commands.AutoShardedBot):
report_id=report_id, report_id=report_id,
) )
await redis.set(key, "1", ex=300) await self.redis.set(key, "1", ex=300)
return row return row
@@ -230,7 +235,7 @@ class Payphone(commands.AutoShardedBot):
user_id=user_id, user_id=user_id,
).update(expires_at=datetime.now(timezone.utc)) ).update(expires_at=datetime.now(timezone.utc))
await redis.set(key, "0", ex=300) await self.redis.set(key, "0", ex=300)
async def get_prefix( async def get_prefix(
self, message: discord.Message | None = None, server_id: int | None = None self, message: discord.Message | None = None, server_id: int | None = None
@@ -282,7 +287,7 @@ class Payphone(commands.AutoShardedBot):
key = constants.PREFIX_TEMPLATE % server_id key = constants.PREFIX_TEMPLATE % server_id
prefix: bytes | None = await redis.get(key) prefix: bytes | None = await self.redis.get(key)
if prefix is not None: if prefix is not None:
prefix = prefix.decode() prefix = prefix.decode()
@@ -297,7 +302,7 @@ class Payphone(commands.AutoShardedBot):
id=server_id, id=server_id,
) )
await redis.set(key, server.prefix, ex=60 * 60) await self.redis.set(key, server.prefix, ex=60 * 60)
prefix = server.prefix prefix = server.prefix
@@ -329,7 +334,7 @@ class Payphone(commands.AutoShardedBot):
await models.Server.filter(id=server_id).update(prefix=prefix) await models.Server.filter(id=server_id).update(prefix=prefix)
await redis.set(constants.PREFIX_TEMPLATE % server_id, prefix, ex=60 * 60) await self.redis.set(constants.PREFIX_TEMPLATE % server_id, prefix, ex=60 * 60)
async def on_command_error( async def on_command_error(
self, context: commands.Context, exception: commands.CommandError self, context: commands.Context, exception: commands.CommandError
@@ -390,6 +395,16 @@ class Payphone(commands.AutoShardedBot):
else: else:
return await super().on_command_error(context, exception) return await super().on_command_error(context, exception)
async def on_error(
self, event_method: str, *args: discord.Any, **kwargs: discord.Any
) -> None:
_, exception, _ = sys.exc_info()
if isinstance(exception, asyncpg.exceptions.InterfaceError):
return
return await super().on_error(event_method, *args, **kwargs)
@property @property
def embed_author(self) -> discord.EmbedAuthor: def embed_author(self) -> discord.EmbedAuthor:
"""The embed author for embeds sent by Payphone. """The embed author for embeds sent by Payphone.
+45 -45
View File
@@ -20,7 +20,6 @@ from payphone.db import utils as dbutils, models
from payphone.cogs import base from payphone.cogs import base
from payphone.cogs.calls import embeds from payphone.cogs.calls import embeds
from payphone.core import constants, checks, censorship, formatting, utils from payphone.core import constants, checks, censorship, formatting, utils
from payphone.core.redis import redis
class Calls(base.Cog): class Calls(base.Cog):
@@ -79,7 +78,7 @@ class Calls(base.Cog):
if len(hung_up_channel_ids) > 0: if len(hung_up_channel_ids) > 0:
await models.Channel.filter(id__in=hung_up_channel_ids).update(call_id=None) await models.Channel.filter(id__in=hung_up_channel_ids).update(call_id=None)
await redis.srem(constants.CHANNELS_ONCALL_SET, *hung_up_channel_ids) await self.bot.redis.srem(constants.CHANNELS_ONCALL_SET, *hung_up_channel_ids)
@commands.command(aliases=["c"]) @commands.command(aliases=["c"])
@commands.guild_only() @commands.guild_only()
@@ -97,7 +96,7 @@ class Calls(base.Cog):
user_id = ctx.author.id user_id = ctx.author.id
channel_id = ctx.channel.id channel_id = ctx.channel.id
is_on_call = await redis.sismember( is_on_call = await self.bot.redis.sismember(
constants.CHANNELS_ONCALL_SET, str(channel_id) constants.CHANNELS_ONCALL_SET, str(channel_id)
) )
@@ -107,7 +106,7 @@ class Calls(base.Cog):
) )
return return
is_searching = await redis.sismember( is_searching = await self.bot.redis.sismember(
constants.CHANNELS_SEARCH_QUEUE, str(channel_id) constants.CHANNELS_SEARCH_QUEUE, str(channel_id)
) )
@@ -156,7 +155,7 @@ class Calls(base.Cog):
if last_calls_rss_channels_map[call_rs.call_id] != call_rs.channel_id: if last_calls_rss_channels_map[call_rs.call_id] != call_rs.channel_id:
last_calls_other_channels_ids.add(call_rs.channel_id) last_calls_other_channels_ids.add(call_rs.channel_id)
other_channel_id: int = await redis.spop(constants.CHANNELS_SEARCH_QUEUE) other_channel_id: int = await self.bot.redis.spop(constants.CHANNELS_SEARCH_QUEUE)
i = 0 i = 0
while True: while True:
@@ -165,7 +164,7 @@ class Calls(base.Cog):
other_channel_id = None other_channel_id = None
break break
# Redis returns the ID as a bytes string. # self.bot.redis returns the ID as a bytes string.
other_channel_id = int(other_channel_id) other_channel_id = int(other_channel_id)
if i == 5: if i == 5:
@@ -174,9 +173,9 @@ class Calls(base.Cog):
i += 1 i += 1
if other_channel_id in last_calls_other_channels_ids: if other_channel_id in last_calls_other_channels_ids:
await redis.sadd(constants.CHANNELS_SEARCH_QUEUE, str(other_channel_id)) await self.bot.redis.sadd(constants.CHANNELS_SEARCH_QUEUE, str(other_channel_id))
other_channel_id = await redis.spop(constants.CHANNELS_SEARCH_QUEUE) other_channel_id = await self.bot.redis.spop(constants.CHANNELS_SEARCH_QUEUE)
if other_channel_id is None: if other_channel_id is None:
break break
@@ -188,7 +187,7 @@ class Calls(base.Cog):
channel = await dbutils.get_channel(ctx.channel) channel = await dbutils.get_channel(ctx.channel)
if other_channel_id is not None: if other_channel_id is not None:
await redis.sadd( await self.bot.redis.sadd(
constants.CHANNELS_ONCALL_SET, str(channel_id), str(other_channel_id) constants.CHANNELS_ONCALL_SET, str(channel_id), str(other_channel_id)
) )
@@ -217,12 +216,12 @@ class Calls(base.Cog):
).update(call=call) ).update(call=call)
except errors.DiscordException: except errors.DiscordException:
await redis.srem( await self.bot.redis.srem(
constants.CHANNELS_ONCALL_SET, constants.CHANNELS_ONCALL_SET,
str(channel_id), str(channel_id),
str(other_channel_id), str(other_channel_id),
) )
await redis.sadd(constants.CHANNELS_SEARCH_QUEUE, str(channel_id)) await self.bot.redis.sadd(constants.CHANNELS_SEARCH_QUEUE, str(channel_id))
msg_phone_answered = "" msg_phone_answered = ""
await ctx.send( await ctx.send(
@@ -234,7 +233,7 @@ class Calls(base.Cog):
) )
else: else:
await redis.sadd(constants.CHANNELS_SEARCH_QUEUE, str(channel_id)) await self.bot.redis.sadd(constants.CHANNELS_SEARCH_QUEUE, str(channel_id))
await ctx.send( await ctx.send(
( (
@@ -259,7 +258,7 @@ class Calls(base.Cog):
user_id = ctx.author.id user_id = ctx.author.id
channel_id = ctx.channel.id channel_id = ctx.channel.id
is_on_call = await redis.sismember( is_on_call = await self.bot.redis.sismember(
constants.CHANNELS_ONCALL_SET, str(channel_id) constants.CHANNELS_ONCALL_SET, str(channel_id)
) )
@@ -271,7 +270,7 @@ class Calls(base.Cog):
"channels" "channels"
) )
await redis.sadd(constants.CALL_IDS_TO_FLUSH, call.id) await self.bot.redis.sadd(constants.CALL_IDS_TO_FLUSH, call.id)
call.ended_at = datetime.now(timezone.utc) call.ended_at = datetime.now(timezone.utc)
await call.save() await call.save()
@@ -290,7 +289,7 @@ class Calls(base.Cog):
except errors.DiscordException: except errors.DiscordException:
pass pass
await redis.srem( await self.bot.redis.srem(
constants.CHANNELS_ONCALL_SET, constants.CHANNELS_ONCALL_SET,
*( *(
[str(channel_id)] [str(channel_id)]
@@ -337,7 +336,7 @@ class Calls(base.Cog):
if last_calls_rss_channels_map[call_rs.call_id] != call_rs.channel_id: if last_calls_rss_channels_map[call_rs.call_id] != call_rs.channel_id:
last_calls_other_channels_ids.add(call_rs.channel_id) last_calls_other_channels_ids.add(call_rs.channel_id)
other_channel_id: int = await redis.spop(constants.CHANNELS_SEARCH_QUEUE) other_channel_id: int = await self.bot.redis.spop(constants.CHANNELS_SEARCH_QUEUE)
i = 0 i = 0
while True: while True:
@@ -346,7 +345,7 @@ class Calls(base.Cog):
other_channel_id = None other_channel_id = None
break break
# Redis returns the ID as a bytes string. # self.bot.redis returns the ID as a bytes string.
other_channel_id = int(other_channel_id) other_channel_id = int(other_channel_id)
if i == 5: if i == 5:
@@ -355,9 +354,9 @@ class Calls(base.Cog):
i += 1 i += 1
if other_channel_id in last_calls_other_channels_ids: if other_channel_id in last_calls_other_channels_ids:
await redis.sadd(constants.CHANNELS_SEARCH_QUEUE, str(other_channel_id)) await self.bot.redis.sadd(constants.CHANNELS_SEARCH_QUEUE, str(other_channel_id))
other_channel_id = await redis.spop(constants.CHANNELS_SEARCH_QUEUE) other_channel_id = await self.bot.redis.spop(constants.CHANNELS_SEARCH_QUEUE)
if other_channel_id is None: if other_channel_id is None:
break break
@@ -367,7 +366,7 @@ class Calls(base.Cog):
break break
if other_channel_id is not None: if other_channel_id is not None:
await redis.sadd( await self.bot.redis.sadd(
constants.CHANNELS_ONCALL_SET, str(channel_id), str(other_channel_id) constants.CHANNELS_ONCALL_SET, str(channel_id), str(other_channel_id)
) )
@@ -396,12 +395,12 @@ class Calls(base.Cog):
).update(call=call) ).update(call=call)
except errors.DiscordException: except errors.DiscordException:
await redis.srem( await self.bot.redis.srem(
constants.CHANNELS_ONCALL_SET, constants.CHANNELS_ONCALL_SET,
str(channel_id), str(channel_id),
str(other_channel_id), str(other_channel_id),
) )
await redis.sadd(constants.CHANNELS_SEARCH_QUEUE, str(channel_id)) await self.bot.redis.sadd(constants.CHANNELS_SEARCH_QUEUE, str(channel_id))
msg_phone_answered = "" msg_phone_answered = ""
await ctx.send( await ctx.send(
@@ -417,7 +416,7 @@ class Calls(base.Cog):
) )
else: else:
await redis.sadd(constants.CHANNELS_SEARCH_QUEUE, str(channel_id)) await self.bot.redis.sadd(constants.CHANNELS_SEARCH_QUEUE, str(channel_id))
channel.call = None channel.call = None
await channel.save() await channel.save()
@@ -441,7 +440,7 @@ class Calls(base.Cog):
channel_id = ctx.channel.id channel_id = ctx.channel.id
is_on_call = await redis.sismember( is_on_call = await self.bot.redis.sismember(
constants.CHANNELS_ONCALL_SET, str(channel_id) constants.CHANNELS_ONCALL_SET, str(channel_id)
) )
@@ -452,13 +451,13 @@ class Calls(base.Cog):
"channels" "channels"
) )
await redis.sadd(constants.CALL_IDS_TO_FLUSH, call.id) await self.bot.redis.sadd(constants.CALL_IDS_TO_FLUSH, call.id)
other_channel: models.Channel = find( other_channel: models.Channel = find(
lambda c: c.id != channel_id, call.channels lambda c: c.id != channel_id, call.channels
) )
await redis.srem( await self.bot.redis.srem(
constants.CHANNELS_ONCALL_SET, constants.CHANNELS_ONCALL_SET,
*( *(
[str(channel_id)] [str(channel_id)]
@@ -489,12 +488,12 @@ class Calls(base.Cog):
call.ended_at = datetime.now(timezone.utc) call.ended_at = datetime.now(timezone.utc)
await call.save() await call.save()
is_searching = await redis.sismember( is_searching = await self.bot.redis.sismember(
constants.CHANNELS_SEARCH_QUEUE, str(channel_id) constants.CHANNELS_SEARCH_QUEUE, str(channel_id)
) )
if is_searching: if is_searching:
await redis.srem(constants.CHANNELS_SEARCH_QUEUE, str(channel_id)) await self.bot.redis.srem(constants.CHANNELS_SEARCH_QUEUE, str(channel_id))
await ctx.send(f"☎️ {secrets.choice(constants.MSGS_PHONE_NO_ANSWER)}") await ctx.send(f"☎️ {secrets.choice(constants.MSGS_PHONE_NO_ANSWER)}")
@@ -577,7 +576,7 @@ class Calls(base.Cog):
call.ended_at = datetime.now(timezone.utc) call.ended_at = datetime.now(timezone.utc)
await call.save() await call.save()
await redis.sadd(constants.CALL_IDS_TO_FLUSH, call.id) await self.bot.redis.sadd(constants.CALL_IDS_TO_FLUSH, call.id)
updated_channels = [] updated_channels = []
@@ -587,7 +586,7 @@ class Calls(base.Cog):
await models.Channel.bulk_update(updated_channels, ["call_id"]) await models.Channel.bulk_update(updated_channels, ["call_id"])
await redis.srem( await self.bot.redis.srem(
constants.CHANNELS_ONCALL_SET, constants.CHANNELS_ONCALL_SET,
str(updated_channels[0]), str(updated_channels[0]),
str(updated_channels[1]), str(updated_channels[1]),
@@ -597,7 +596,7 @@ class Calls(base.Cog):
other_channel = find(lambda c: c.id != channel_id, updated_channels) other_channel = find(lambda c: c.id != channel_id, updated_channels)
await redis.srem( await self.bot.redis.srem(
constants.CHANNELS_ONCALL_SET, str(other_channel.id), str(channel_id) constants.CHANNELS_ONCALL_SET, str(other_channel.id), str(channel_id)
) )
@@ -666,7 +665,7 @@ class Calls(base.Cog):
user_id = message.author.id user_id = message.author.id
channel_id = message.channel.id channel_id = message.channel.id
is_on_call = await redis.sismember( is_on_call = await self.bot.redis.sismember(
constants.CHANNELS_ONCALL_SET, str(channel_id) constants.CHANNELS_ONCALL_SET, str(channel_id)
) )
@@ -686,7 +685,7 @@ class Calls(base.Cog):
) )
except exceptions.DoesNotExist: except exceptions.DoesNotExist:
await redis.srem(constants.CHANNELS_ONCALL_SET, str(channel_id)) await self.bot.redis.srem(constants.CHANNELS_ONCALL_SET, str(channel_id))
return return
other_channel: models.Channel = find( other_channel: models.Channel = find(
@@ -755,6 +754,7 @@ class Calls(base.Cog):
if message.reference: if message.reference:
embed, replying_message = await embeds.ReplyEmbed( embed, replying_message = await embeds.ReplyEmbed(
self.bot.redis,
message.reference, call_id=call.id message.reference, call_id=call.id
) )
@@ -769,7 +769,7 @@ class Calls(base.Cog):
wait=True, wait=True,
) )
pipe = redis.pipeline() pipe = self.bot.redis.pipeline()
pipe.hset( pipe.hset(
constants.CALL_MESSAGES_TEMPLATE % call.id, constants.CALL_MESSAGES_TEMPLATE % call.id,
@@ -815,7 +815,7 @@ class Calls(base.Cog):
) )
if replying_to_id is not None: if replying_to_id is not None:
other_replies = await redis.hget( other_replies = await self.bot.redis.hget(
constants.CALL_MESSAGE_REPLIES_TEMPLATE % call.id, replying_to_id constants.CALL_MESSAGE_REPLIES_TEMPLATE % call.id, replying_to_id
) )
@@ -858,7 +858,7 @@ class Calls(base.Cog):
if channel.call_id is None: if channel.call_id is None:
return return
message_json = await redis.hget( message_json = await self.bot.redis.hget(
constants.CALL_MESSAGES_TEMPLATE % channel.call_id, message_id constants.CALL_MESSAGES_TEMPLATE % channel.call_id, message_id
) )
@@ -871,7 +871,7 @@ class Calls(base.Cog):
message_dict["was_deleted"] = True message_dict["was_deleted"] = True
await redis.hset( await self.bot.redis.hset(
constants.CALL_MESSAGES_TEMPLATE % channel.call_id, constants.CALL_MESSAGES_TEMPLATE % channel.call_id,
message.id, message.id,
orjson.dumps(message_dict), orjson.dumps(message_dict),
@@ -892,7 +892,7 @@ class Calls(base.Cog):
# This message was already deleted. # This message was already deleted.
pass pass
message_replies = await redis.hget( message_replies = await self.bot.redis.hget(
constants.CALL_MESSAGE_REPLIES_TEMPLATE % channel.call_id, message.id constants.CALL_MESSAGE_REPLIES_TEMPLATE % channel.call_id, message.id
) )
@@ -937,7 +937,7 @@ class Calls(base.Cog):
if channel.call_id is None: if channel.call_id is None:
return return
message_json = await redis.hget( message_json = await self.bot.redis.hget(
constants.CALL_MESSAGES_TEMPLATE % channel.call_id, message_id constants.CALL_MESSAGES_TEMPLATE % channel.call_id, message_id
) )
@@ -967,13 +967,13 @@ class Calls(base.Cog):
blocked_word = censorship.moderate(content) blocked_word = censorship.moderate(content)
iteration = int( iteration = int(
await redis.hget( await self.bot.redis.hget(
constants.CALL_MESSAGE_CONTENT_ITERATIONS_TEMPLATE % channel.call_id, constants.CALL_MESSAGE_CONTENT_ITERATIONS_TEMPLATE % channel.call_id,
message.id, message.id,
) )
) )
pipe = redis.pipeline() pipe = self.bot.redis.pipeline()
pipe.hincrby( pipe.hincrby(
constants.CALL_MESSAGE_CONTENT_ITERATIONS_TEMPLATE % channel.call_id, constants.CALL_MESSAGE_CONTENT_ITERATIONS_TEMPLATE % channel.call_id,
@@ -1031,13 +1031,13 @@ class Calls(base.Cog):
call_id = channel.call_id call_id = channel.call_id
other_channel_id = None other_channel_id = None
other_channel_message_id = await redis.hget( other_channel_message_id = await self.bot.redis.hget(
constants.CALL_MESSAGE_FROM_PROPAGATION_TEMPLATE % call_id, constants.CALL_MESSAGE_FROM_PROPAGATION_TEMPLATE % call_id,
payload.message_id, payload.message_id,
) )
if other_channel_message_id is None: if other_channel_message_id is None:
other_channel_message_json = await redis.hget( other_channel_message_json = await self.bot.redis.hget(
constants.CALL_MESSAGES_TEMPLATE % call_id, payload.message_id constants.CALL_MESSAGES_TEMPLATE % call_id, payload.message_id
) )
@@ -1093,13 +1093,13 @@ class Calls(base.Cog):
call_id = channel.call_id call_id = channel.call_id
other_channel_id = None other_channel_id = None
other_channel_message_id = await redis.hget( other_channel_message_id = await self.bot.redis.hget(
constants.CALL_MESSAGE_FROM_PROPAGATION_TEMPLATE % call_id, constants.CALL_MESSAGE_FROM_PROPAGATION_TEMPLATE % call_id,
payload.message_id, payload.message_id,
) )
if other_channel_message_id is None: if other_channel_message_id is None:
other_channel_message_json = await redis.hget( other_channel_message_json = await self.bot.redis.hget(
constants.CALL_MESSAGES_TEMPLATE % call_id, payload.message_id constants.CALL_MESSAGES_TEMPLATE % call_id, payload.message_id
) )
+9 -5
View File
@@ -2,17 +2,19 @@ import discord
import orjson import orjson
import redis.asyncio as aredis
from payphone.db import models from payphone.db import models
from payphone.core import constants, formatting from payphone.core import constants, formatting
from payphone.core.redis import redis
async def ReplyEmbed( async def ReplyEmbed(
reference: discord.MessageReference, call_id: int redis: aredis.Redis, reference: discord.MessageReference, call_id: int
) -> tuple[discord.Embed | None, models.Message | None]: ) -> tuple[discord.Embed | None, models.Message | None]:
"""Generates the embed sent on calls to represent replies. """Generates the embed sent on calls to represent replies.
Args: Args:
redis (redis.asyncio.Redis): An instance of a Redis connection handler.
reference (discord.MessageReference): The message reference. reference (discord.MessageReference): The message reference.
call_id (int): The ID of the call the message was sent in. call_id (int): The ID of the call the message was sent in.
@@ -43,9 +45,11 @@ async def ReplyEmbed(
message = models.Message(**orjson.loads(unflushed_message)) message = models.Message(**orjson.loads(unflushed_message))
unflushed_message_content_iteration = int(await redis.hget( unflushed_message_content_iteration = int(
constants.CALL_MESSAGE_CONTENT_ITERATIONS_TEMPLATE % call_id, message.id await redis.hget(
)) constants.CALL_MESSAGE_CONTENT_ITERATIONS_TEMPLATE % call_id, message.id
)
)
unflushed_message_content = await redis.hget( unflushed_message_content = await redis.hget(
constants.CALL_MESSAGE_CONTENTS_TEMPLATE % call_id, constants.CALL_MESSAGE_CONTENTS_TEMPLATE % call_id,
constants.CALL_MESSAGE_CONTENTS_HASH_TEMPLATE constants.CALL_MESSAGE_CONTENTS_HASH_TEMPLATE
+8 -10
View File
@@ -9,7 +9,6 @@ import discord
from discord import errors from discord import errors
from discord.ext import commands from discord.ext import commands
import tortoise
from tortoise import transactions, expressions from tortoise import transactions, expressions
from procs import flush_messages from procs import flush_messages
@@ -19,7 +18,6 @@ from payphone.db import utils, models
from payphone.cogs import base from payphone.cogs import base
from payphone.cogs.mods import embeds, views from payphone.cogs.mods import embeds, views
from payphone.core import checks, converters, constants, formatting as fmt from payphone.core import checks, converters, constants, formatting as fmt
from payphone.core.redis import redis
class Mods(base.Cog): class Mods(base.Cog):
@@ -245,9 +243,9 @@ class Mods(base.Cog):
- `[<reason>]`: The reason of the shutdown. - `[<reason>]`: The reason of the shutdown.
""" """
oncall_channel_ids = list(await redis.smembers(constants.CHANNELS_ONCALL_SET)) oncall_channel_ids = list(await self.bot.redis.smembers(constants.CHANNELS_ONCALL_SET))
searching_channel_ids = list( searching_channel_ids = list(
await redis.smembers(constants.CHANNELS_SEARCH_QUEUE) await self.bot.redis.smembers(constants.CHANNELS_SEARCH_QUEUE)
) )
channel_ids = [int(c) for c in oncall_channel_ids] + [ channel_ids = [int(c) for c in oncall_channel_ids] + [
@@ -272,9 +270,9 @@ class Mods(base.Cog):
await asyncio.sleep(seconds) await asyncio.sleep(seconds)
oncall_channel_ids = list(await redis.smembers(constants.CHANNELS_ONCALL_SET)) oncall_channel_ids = list(await self.bot.redis.smembers(constants.CHANNELS_ONCALL_SET))
searching_channel_ids = list( searching_channel_ids = list(
await redis.smembers(constants.CHANNELS_SEARCH_QUEUE) await self.bot.redis.smembers(constants.CHANNELS_SEARCH_QUEUE)
) )
channel_ids = [int(c) for c in oncall_channel_ids] + [ channel_ids = [int(c) for c in oncall_channel_ids] + [
@@ -296,13 +294,13 @@ class Mods(base.Cog):
"⚡ Notified all channels of calls hang up. Flushing messages to the DB..." "⚡ Notified all channels of calls hang up. Flushing messages to the DB..."
) )
await redis.delete(constants.CHANNELS_ONCALL_SET) await self.bot.redis.delete(constants.CHANNELS_ONCALL_SET)
calls = await models.Call.filter(ended_at=None) calls = await models.Call.filter(ended_at=None)
call_ids = [call.id for call in calls] call_ids = [call.id for call in calls]
if call_ids: if call_ids:
await redis.sadd(constants.CALL_IDS_TO_FLUSH, *call_ids) await self.bot.redis.sadd(constants.CALL_IDS_TO_FLUSH, *call_ids)
await models.Call.filter(ended_at=None).update( await models.Call.filter(ended_at=None).update(
ended_at=datetime.now(timezone.utc) ended_at=datetime.now(timezone.utc)
@@ -330,11 +328,11 @@ class Mods(base.Cog):
stats = [ stats = [
( (
"On-call Channels", "On-call Channels",
lambda: redis.scard(constants.CHANNELS_ONCALL_SET), lambda: self.bot.redis.scard(constants.CHANNELS_ONCALL_SET),
), ),
( (
"Searching Channels", "Searching Channels",
lambda: redis.scard(constants.CHANNELS_SEARCH_QUEUE), lambda: self.bot.redis.scard(constants.CHANNELS_SEARCH_QUEUE),
), ),
( (
"Messages", "Messages",
+1 -2
View File
@@ -2,7 +2,6 @@ from discord.ext import commands
from payphone.db import utils from payphone.db import utils
from payphone.core import exceptions, constants from payphone.core import exceptions, constants
from payphone.core.redis import redis
def is_moderator(): def is_moderator():
@@ -40,7 +39,7 @@ def is_on_call():
async def predicate(ctx: commands.Context) -> bool: async def predicate(ctx: commands.Context) -> bool:
channel_id = ctx.channel.id channel_id = ctx.channel.id
is_on_call = await redis.sismember( is_on_call = await ctx.bot.redis.sismember(
constants.CHANNELS_ONCALL_SET, str(channel_id) constants.CHANNELS_ONCALL_SET, str(channel_id)
) )
+2 -3
View File
@@ -9,7 +9,6 @@ import orjson
from payphone.db import models from payphone.db import models
from payphone.core import exceptions, constants from payphone.core import exceptions, constants
from payphone.core.redis import redis
class Timedelta(converter.Converter): class Timedelta(converter.Converter):
@@ -82,7 +81,7 @@ class DiscordUserID(converter.Converter):
if channel is None: if channel is None:
raise converter.BadArgument() raise converter.BadArgument()
original_message_id = await redis.hget( original_message_id = await ctx.bot.redis.hget(
constants.CALL_MESSAGE_FROM_PROPAGATION_TEMPLATE constants.CALL_MESSAGE_FROM_PROPAGATION_TEMPLATE
% channel.call_id, % channel.call_id,
ref.message_id, ref.message_id,
@@ -91,7 +90,7 @@ class DiscordUserID(converter.Converter):
if original_message_id is None: if original_message_id is None:
raise converter.BadArgument() raise converter.BadArgument()
original_message_json = await redis.hget( original_message_json = await ctx.bot.redis.hget(
constants.CALL_MESSAGES_TEMPLATE % channel.call_id, constants.CALL_MESSAGES_TEMPLATE % channel.call_id,
int(original_message_id), int(original_message_id),
) )
-6
View File
@@ -1,6 +0,0 @@
from redis import asyncio as aredis
from payphone.core import config
redis = aredis.Redis(host="localhost" if config.IS_DEBUG else "redis")
+5 -2
View File
@@ -3,10 +3,13 @@ async def flush():
import asyncpg.exceptions import asyncpg.exceptions
import redis.asyncio as aredis
from payphone.db import models from payphone.db import models
from payphone.core import constants, utils from payphone.core import constants, utils, config
from payphone.core.redis import redis
redis = aredis.Redis(host="localhost" if config.IS_DEBUG else "redis")
pipe = redis.pipeline() pipe = redis.pipeline()
+33 -3
View File
@@ -15,7 +15,17 @@ def shard(shard_id: int, shard_count: int) -> None:
bot.shard_ids = [shard_id] bot.shard_ids = [shard_id]
bot.shard_count = shard_count bot.shard_count = shard_count
bot.run(config.TOKEN) try:
import uvloop # pylint: disable=import-error
bot.loop = uvloop.new_event_loop()
print(f"Running shard {shard_id} with uvloop.")
except ImportError:
print("Running with default loop.")
finally:
bot.run(config.TOKEN)
def flush_process(): def flush_process():
@@ -23,7 +33,24 @@ def flush_process():
from procs.flush_messages import loop from procs.flush_messages import loop
asyncio.run(loop()) try:
import uvloop # pylint: disable=import-error
uvloop.install()
print("Flushing messages with uvloop.")
except ImportError:
try:
import winloop
winloop.install()
print("Flushing messages with winloop.")
except ImportError:
print("Could not find winloop nor uvloop for messages flushing.")
finally:
asyncio.run(loop())
if __name__ == "__main__": if __name__ == "__main__":
@@ -35,9 +62,12 @@ if __name__ == "__main__":
import httpx import httpx
import redis.asyncio as aredis
from payphone.db import setup, models from payphone.db import setup, models
from payphone.core import config from payphone.core import config
from payphone.core.redis import redis
redis = aredis.Redis(host="localhost" if config.IS_DEBUG else "redis")
async def init(): async def init():
await setup.init() await setup.init()
+1 -1
View File
@@ -6,4 +6,4 @@ do
echo "Retrying migrations..." echo "Retrying migrations..."
done done
uv run --no-dev run.py uv run --no-dev python3 -u run.py