asyncio не умеет работать с HTTP.
Так и было задумано.
asyncio никогда не станет веб-сервером. Он делался как именно event loop для tcp, ssl, unix sockets, pipes и subprocesses. Плюс streaming API.
Веб был сознательно выпилен и теперь то что было лежит в aiohttp. Эта часть просто не дозрела до включения в стандартную библиотеку.
Идея такая:
- WSGI -- синхронный протокол, для asyncio не подходит.
- Какой будет новый стандарт -- неясно никому.
- Пусть для asyncio люди попытаются сделать свои http либы и время покажет у кого получилось лучше.
- Тогда, возможно, и появится новый стандарт.
Что касается меня то я пытаюсь понять какой именно должен быть API для HTTP server, что там должно быть обязательно и что нужно сознательно исключить.
Сейчас делаем это aiorest
Когда поймём, что получилось хорошо в aiorest -- займемся перенесением удачных решений в aiohttp. Там HTTP server слишком уж неудобный. А нужно что-то типа tornado.web, но более симпатичное и приятное.
намедни попробовал свой вариант jsonrpc через xmpp на asyncio переделать с торнады. всетаки медленее однако.
ОтветитьУдалитьвпрочем не исключаю что не совсем эффективно адаптирвал к asyncio. ну и 10% рвзницы не показатель.
ОтветитьУдалитьне понятно почему wsgi не подходит? можешь подробней?
ОтветитьУдалитьА действительно, почему WSGI не подходит? Он же итерирумый объект возвращает, что мешает из него читать асинхронно?
ОтветитьУдалитьПотому что, если отбросить всю шелуху, WSGI это
ОтветитьУдалитьdef app(environ, start_response):
response_headers = [('Content-type', 'text/plain')]
start_response('200 OK', response_headers)
for i in ['a', 'b', 'c']:
yield i
Обратите внимание: функция, которая может вернуть строку или итератор. А никак не asyncio.coroutine. В app нельзя сделать yield from redis.get('key'). WSGI сервер этого не поймёт, не обучен по стандарту.
А если обучить, то это будет уже не PEP 333/3333.
Как-то так.
wsgi сервер уже определяет разницу между строкой и итератором, не вижу проблем в том чтобы добавить определение asyncio.Future,
ОтветитьУдалитьдумаю это проще чем делать новый стандарт. а потом чем фундаментально asyncio.coroutine отличается от генератора?
Коля, если добавить подержку для Future это и будет новый стандарт. WSGI 33333 если хочешь.
ОтветитьУдалитьПотому что все WSGI библиотеки (Django, Flask, Pyramid и нет им числа) с Future работать не умеют.
Возможно, пока еще не умеют, но тем не менее факт. И сколько там надо будет переписать в коде Django чтобы заработало. О middleware не забывай и о прочем.
Может, проще придумать стандарт на asyncio Request/Response (все WSGI библиотеки имеют эти два объекта в том или ином виде) и отойти от WSGI как это сделала tornado?
Я немного поработал с Торнадой, и могу сказать что в ней не wsgi по той причине, что при формировании ответа хэндлер может выбросить исключение или еще как то упасть, поэтому они сначала накапливают вывод, а потом выдают клиенту статус 200 ОК, или не ОК, в зависимости от ситуации.
ОтветитьУдалитьНаверное, для типичного веб-приложения, где просто странички выдаются, это ненужное усложнение, но конкретно в моем проекте, где условно говоря весь сервер обслуживает POST запросы, - это оказалось более чем корректным.
Обработка http(s) запросов по умолчанию должна быть синхронная из-за http status code, и если делать ее асинхронной, значит нужен просто промежуточный буфер, где заголовки, код ответа и тело ответа хранится до тех пор пока запрос не будет полностью обработан либо до явного вызова flush.
Кстати, быстрый взгляд на aiohttp показал - what? В readme описано что? клиент? Такое впечатление, что оно настолько in development, что надо сильно глубоко вникать.
Tornado сильно отличается от WSGI и описанная тобой причина -- только одна из многих.
ОтветитьУдалитьaiohttp -- да, допиливать и допиливать. Но вроде бы есть некое видение того, что хочется получить в конце.
Остальные существующие для asyncio web либы тоже те еще подарочки.