Не удается получить блокировку при попытке синхронизировать команды discord.py

Я пишу своего бота Discord, у которого есть несколько команд. Однако в последнее время появилась необходимость для каждой команды проверять список перед выполнением. Итак, естественно, правильнее всего будет синхронизировать команды примерно так:

import discord
from discord.ext import commands
from time import sleep
import subprocess
import logging
import asyncio

client = commands.Bot(command_prefix='>>', case_insensitive=True)
token = 'lul'
logging.basicConfig(level=logging.INFO)
lock = None

@client.event
async def on_ready():
    lock = asyncio.Lock()
    print(f'Logged in as {client.user}')

@client.command()
async def test(ctx, members : commands.Greedy[discord.Member]):
    await ctx.send(len(members))
    await ctx.send('approaching critical section')
    with await lock:
        await ctx.send('in critical section')
        time.sleep(10)
    await ctx.send('exited critical section')

Итак, если бы вы вызывали команду с >>test @abs @asda, вы ожидали бы получить вывод:

2
approaching critical section
in critical section
exited critical section

Но вместо этого мы получаем следующее:

2
approaching critical section

Итак, это означает, что сопрограмма не попадает в критическую секцию. Может случиться так, что сопрограмма выйдет из строя или истечет время ожидания из-за невозможности получить блокировку (если это действительно так).

Тем не менее, помощь в решении этой проблемы очень ценится.


person Platon Makovsky    schedule 22.04.2020    source источник


Ответы (1)


Вам следует использовать async with инструкцию вместо with await. Вы также должны создать блокировку в глобальном пространстве имен и использовать asyncio.sleep вместо time.sleep.

client = commands.Bot(command_prefix='>>', case_insensitive=True)
lock = asyncio.Lock()  # Doesn't require event loop

@client.command()
async def test(ctx, members : commands.Greedy[discord.Member]):
    await ctx.send(len(members))
    await ctx.send('approaching critical section')
    async with lock:
        await ctx.send('in critical section')
        await asyncio.sleep(10)
    await ctx.send('exited critical section')
person Patrick Haugh    schedule 23.04.2020