суббота, 5 апреля 2014 г.

asyncio и HTTP

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, но более симпатичное и приятное.

9 комментариев:

  1. намедни попробовал свой вариант jsonrpc через xmpp на asyncio переделать с торнады. всетаки медленее однако.

    ОтветитьУдалить
  2. впрочем не исключаю что не совсем эффективно адаптирвал к asyncio. ну и 10% рвзницы не показатель.

    ОтветитьУдалить
  3. не понятно почему wsgi не подходит? можешь подробней?

    ОтветитьУдалить
  4. А действительно, почему WSGI не подходит? Он же итерирумый объект возвращает, что мешает из него читать асинхронно?

    ОтветитьУдалить
  5. Потому что, если отбросить всю шелуху, 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.

    Как-то так.

    ОтветитьУдалить
  6. wsgi сервер уже определяет разницу между строкой и итератором, не вижу проблем в том чтобы добавить определение asyncio.Future,
    думаю это проще чем делать новый стандарт. а потом чем фундаментально asyncio.coroutine отличается от генератора?

    ОтветитьУдалить
  7. Коля, если добавить подержку для Future это и будет новый стандарт. WSGI 33333 если хочешь.

    Потому что все WSGI библиотеки (Django, Flask, Pyramid и нет им числа) с Future работать не умеют.

    Возможно, пока еще не умеют, но тем не менее факт. И сколько там надо будет переписать в коде Django чтобы заработало. О middleware не забывай и о прочем.

    Может, проще придумать стандарт на asyncio Request/Response (все WSGI библиотеки имеют эти два объекта в том или ином виде) и отойти от WSGI как это сделала tornado?

    ОтветитьУдалить
  8. Я немного поработал с Торнадой, и могу сказать что в ней не wsgi по той причине, что при формировании ответа хэндлер может выбросить исключение или еще как то упасть, поэтому они сначала накапливают вывод, а потом выдают клиенту статус 200 ОК, или не ОК, в зависимости от ситуации.

    Наверное, для типичного веб-приложения, где просто странички выдаются, это ненужное усложнение, но конкретно в моем проекте, где условно говоря весь сервер обслуживает POST запросы, - это оказалось более чем корректным.

    Обработка http(s) запросов по умолчанию должна быть синхронная из-за http status code, и если делать ее асинхронной, значит нужен просто промежуточный буфер, где заголовки, код ответа и тело ответа хранится до тех пор пока запрос не будет полностью обработан либо до явного вызова flush.

    Кстати, быстрый взгляд на aiohttp показал - what? В readme описано что? клиент? Такое впечатление, что оно настолько in development, что надо сильно глубоко вникать.

    ОтветитьУдалить
  9. Tornado сильно отличается от WSGI и описанная тобой причина -- только одна из многих.
    aiohttp -- да, допиливать и допиливать. Но вроде бы есть некое видение того, что хочется получить в конце.
    Остальные существующие для asyncio web либы тоже те еще подарочки.

    ОтветитьУдалить