Не удается получить блокировку при попытке синхронизировать команды discord.py - PullRequest
0 голосов
/ 22 апреля 2020

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

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

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

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

1 Ответ

1 голос
/ 23 апреля 2020

Вы должны использовать оператор 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')
...