• XSS.stack #1 – первый литературный журнал от юзеров форума

При использовании aiofiles происходят баги, HELP

РЕШЕНИЕ!
на глобальном уровне определить мютекс
Код:
socks4lock = asyncio.Lock()
socks5lock = asyncio.Lock()
и потом используй его перед записью в файл:
Код:
for proxy in proxies['data']:
    if proxy['protocols'][0] == 'socks4':
        async with socks4lock:
            async with aiof.open('socks4.txt', 'a') as file:
                await file.write(f"{proxy['ip']}:{proxy['port']}\n")
                await file.flush()
                await file.close()
    elif proxy['protocols'][0] == 'socks5':
        async with socks5lock:
            async with aiof.open('socks5.txt', 'a') as file:
                await file.write(f"{proxy['ip']}:{proxy['port']}\n")
                await file.flush()
                await file.close()
Немного оффтоп.
И всё же await file.close() лишний. Хоть ошибки и не вызывает, это просто не имеет смысла, так как используется контекстный менеджер (async with).
Кроме того, если функция, которая исполняет этот код, вызывается последовательно (а не вызываются много экземпляров с помощью asyncio.create_task), то asyncio.Lock не нужен. Хотя раз есть проблемы с синхронизацией, значит функции вызываются одновременно. В этом случае более качественным решением будет завести очередь (asyncio.Queue) и в этой функции парсить и складывать в эту очередь, а в отедльной корутине последовательно писать в файл. Ну и последнее, вызывать функцию open в каждой итерации цикла не очень хорошая идея, не смертельно, и даже работать будет, но в целом моветон.

Примерно вот так могло выглядеть решение с очередью. В зависимости от того непрерывно поступают данные, или нужно выполнить парсинг один раз можно написать условия заверешния queue_handler.
Код:
import asyncio
import aiofiles as aiof

queue = asyncio.Queue()


async def queue_handler():
    try:
        socks4_file = await aiof.open('socks4.txt', 'a')
        socks5_file = await aiof.open('socks5.txt', 'a')
        while True:
            proto, line = await queue.get()
            file = socks4_file if proto == 'socks4' else socks5_file
            await file.write(line)
            await file.flush()
    finally:
        await socks4_file.close()
        await socks5_file.close()


async def on_new_proxies(proxies):
    for proxy in proxies['data']:
        await queue.put((proxy['protocols'][0], f"{proxy['ip']}:{proxy['port']}\n"))
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Немного оффтоп.
И всё же await file.close() лишний. Хоть ошибки и не вызывает, это просто не имеет смысла, так как используется контекстный менеджер (async with).
Кроме того, если функция, которая исполняет этот код, вызывается последовательно (а не вызываются много экземпляров с помощью asyncio.create_task), то asyncio.Lock не нужен. Хотя раз есть проблемы с синхронизацией, значит функции вызываются одновременно. В этом случае более качественным решением будет завести очередь (asyncio.Queue) и в этой функции парсить и складывать в эту очередь, а в отедльной корутине последовательно писать в файл. Ну и последнее, вызывать функцию open в каждой итерации цикла не очень хорошая идея, не смертельно, и даже работать будет, но в целом моветон.

Примерно вот так могло выглядеть решение с очередью. В зависимости от того непрерывно поступают данные, или нужно выполнить парсинг один раз можно написать условия заверешния queue_handler.
Код:
import asyncio
import aiofiles as aiof

queue = asyncio.Queue()


async def queue_handler():
    try:
        socks4_file = await aiof.open('socks4.txt', 'a')
        socks5_file = await aiof.open('socks5.txt', 'a')
        while True:
            proto, line = await queue.get()
            file = socks4_file if proto == 'socks4' else socks5_file
            await file.write(line)
            await file.flush()
    finally:
        await socks4_file.close()
        await socks5_file.close()


async def on_new_proxies(proxies):
    for proxy in proxies['data']:
        await queue.put((proxy['protocols'][0], f"{proxy['ip']}:{proxy['port']}\n"))
да бро таким методом и делаю проекты сейчас, но все же спасибо за ответ. Можешь посмотреть и другие посты, выложил несколько чекеров
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх