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

View File

@ -2,3 +2,4 @@ import prometheus_client
achievements_achieved = prometheus_client.Counter("abr_achievements", "Achievements achieved by 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")