fix concurrency issue by serializing role transfers

This commit is contained in:
osmarks 2021-04-15 13:15:17 +01:00
parent 8ae4fa22cb
commit 4f54f2d058
2 changed files with 19 additions and 12 deletions

View File

@ -2,22 +2,28 @@ import util
import random import random
import logging import logging
import discord import discord
import asyncio
import metrics import metrics
role_transfer_lock = asyncio.Lock()
def setup(bot): def setup(bot):
@bot.listen() @bot.listen()
async def on_message(message): async def on_message(message):
if message.guild.id == util.config["esoserver"]["id"]: if message.guild.id == util.config["esoserver"]["id"]:
async with role_transfer_lock: # prevent concurrency horrors - serialize accesses, probably
for role in message.role_mentions: for role in message.role_mentions:
if role.id == util.config["esoserver"]["transfer_role"]: # transfer the role from sender to other pinged person if role.id == util.config["esoserver"]["transfer_role"]: # transfer the role from sender to other pinged person
if len(message.mentions) == 1: if len(message.mentions) == 1:
await message.author.remove_roles(role, reason="untransfer unrole") await message.author.remove_roles(role, reason="untransfer unrole")
await message.mentions[0].add_roles(role, reason="transfer role") await message.mentions[0].add_roles(role, reason="transfer role")
metrics.role_transfers.inc()
return return
for user in message.mentions: for user in message.mentions:
for role in user.roles: for role in user.roles:
if role.id == util.config["esoserver"]["transfer_role"]: # transfer from pingee to pinger if role.id == util.config["esoserver"]["transfer_role"]: # transfer from pingee to pinger
await user.remove_roles(role, reason="untransfer unrole") await user.remove_roles(role, reason="untransfer unrole")
await message.author.add_roles(role, reason="transfer role") await message.author.add_roles(role, reason="transfer role")
metrics.role_transfers.inc()
return return

View File

@ -2,3 +2,4 @@ import prometheus_client
achievements_achieved = prometheus_client.Counter("abr_achievements", "Achievements achieved by users") achievements_achieved = prometheus_client.Counter("abr_achievements", "Achievements achieved by users")
reminders_fired = prometheus_client.Counter("abr_reminders", "Reminders successfully delivered to users") reminders_fired = prometheus_client.Counter("abr_reminders", "Reminders successfully delivered to users")
role_transfers = prometheus_client.Counter("abr_role_transfers", "Times the esoserver transferable role has been transferred")