Что будет с ошибочными соединениями в aiohttp.ClientSession () с точки зрения дескрипторов файлов ОС? - PullRequest
0 голосов
/ 18 июня 2019

На самом деле у меня есть два вопроса, связанных с абстракцией сессии:

1. Что происходит с ошибочными соединениями, произошедшими в течение сеанса?

О пункте (1): на самом деле я пишу асинхронный парсер. Представьте, что я снова использую один и тот же сеанс (обработка удаленных исключений при сбое сети):

loop = asyncio.get_event_loop()
session = aiohttp.ClientSession()
loop.run_until_complete(asyncio.gather(*(get_url(session, url) for url in [over 9000 urls])))

async def get_url(session, url, retries=500, proxy={...}):
   attempt = 1
   while attempt < retries:
       async with session.get(url) as response:
           if response.status == 200:
               return await response.text()
           else:
               attempt += 1

loop.run_until_complete(session.close())

Также прокси - это пул бесплатных прокси, поэтому ответы часто бывают безуспешными.

Сбой синтаксического анализа с OSError «слишком много открытых файлов» при попытке установить другое соединение. Я полагаю, что это происходит из-за открытых файловых дескрипторов ОС. Как проверить правильность моего предложения или неправильное обращение с ресурсами в другом месте? Это было единственное место в моем коде, где я получал доступ к системным ресурсам без менеджера контекста. Прав ли я, что неудачные запросы оставят открытые дескрипторы мусорных файлов в системе в долгосрочной перспективе, что приведет к OSError 24? Может ли использование этого сеанса открыть больше дескрипторов файлов, чем ограничен пул соединений (по умолчанию 100 для сеанса клиента aiohttm)?

2. Что такое случаи использования сеанса (особенно повторного использования сеанса)?

Концепция сессии мне тоже неясна. Я знаю, что это удобно, когда мне нужно упорствовать, например, сеанс входа в систему, конкретные куки для каждого запроса. Но с точки зрения парсера (скребка) мне такие преимущества не нужны. В этом случае, если я создаю сессию в менеджере контекста для каждого запроса, это адекватно или чрезмерно, также относительно производительности? Как (обработка исключений при сбое сети удалена):

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*(get_url(url) for url in [over 9000 urls])))

async def get_url(url, retries=500, proxy={...}):
    attempt = 1
    while attempt < retries:
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                if response.status == 200:
                    return await response.text()
                else:
                    attempt += 1

Что такое случай использования сеанса вообще, когда делиться им, а когда он не нужен?

...