четверг, 17 февраля 2011 г.

RESTAS и Mongrel2

Hunchentoot предоставляет очень удобный интерфейс, но есть некоторые сомнения о возможности использования его под высокой нагрузкой, всё таки схема поток на соединения имеет достаточно понятные пределы для масштабирования. Правда, судя по патчам ITA они таки используют Hunchentoot под достаточно высокой нагрузкой, но хотелось бы всё таки иметь и другое решение. Писать асинхронный веб-сервер на CL, который бы предоставлял уровень сервиса сопоставимый с Hunchentoot, меня сейчас не прельщает. Я достаточно долго хотел просто форкнуть Hunchentoot, переделать его на базе iolib с использованием epoll и т.п., но сейчас уже отказался от этой идеи. Отказался после того, как узнал о существовании Mongrel2, который обещает все плюшки асинхронного веб-сервера и при этом не зависит от языка.

Сейчас моя самая большая цель - научить RESTAS работать с Mongrel2 (сохранив при этом возможность работать и с Hunchentoot). Но есть проблема, что Mongrel2 не предоставляет такого интерфейса, как Hunchentoot, он только умеет обрабатывать HTTP и всё. Соответственно, задача сводится фактически к вырыванию довольно больших кусков кода из Hunchentoot и адаптации их для Mongrel2. Но в данный момент я не имею достаточных временных ресурсов для выполнения этой работы. Отсюда и вопрос. Нет ли желающих помочь в этом (достойном) деле? ;)

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

  1. я предлагаю помощь, но смотри сам: у меня нет опыта с промышленным лиспом. если тебе интересно, напиши.
    с асинхронными задачами, впрочем, дело имел.

    ОтветитьУдалить
  2. @Alkhimov

    Интересно ) Только до асинхронных задач надо ещё добраться. Для начала надо предоставить одинаковый интерфейс для Hunchentoot и Mongrel2. Интерфейс Hunchentoot для работы с request и reply я считаю достаточно удачным, так что полагаю надо отталкиваться от него. Т.е. для Mongrel2 надо во-первых реализовать аналогичные интерфейсы, или почти аналогичные. Это надо разбирать код Hunchentoot и переписывать его для Mongrel2.

    Вообще, можно поставить задачу шире, и делать общий слой взаимодействия с веб-серверами, типа Hunchentoot, Mongrel2, FastCGI и т.п.

    ОтветитьУдалить
  3. Поучаствую с удовольствием

    ОтветитьУдалить
  4. А как ты собираешься делать связку lisp c Mongrel? Через ZeroMQ?

    ОтветитьУдалить
  5. @Dmitry

    Поравочка, с Mongrel2 )) Да, конечно, через ZeroMQ. Собственно, эта часть самая простая и уже реализована. Есть https://github.com/vseloved/cl-mongrel2, который я форкнул.

    ОтветитьУдалить
  6. Весьма интересная задача, эх сейчас для меня не резон( Возможно через 1-2 месяца, если будет всё ещё актуально.

    ОтветитьУдалить
  7. Мне эта мысль приходила тоже (о выделении общего API). А последних несколько дней крутится в голове особенно!

    Я хочу предложить выделение общего API для работы с веб серверами в качестве проекта для google summer of code под руководством lispnyc.

    Не знал про mongrel2. Я думал например использовать этот API чтобы встроить ECL в апач или в nginx, либо ABCL на google app engine.

    API конечно лучше делать на основе того, что сейчас есть в hunchentoot, чтобы можно было запускать существующие веб приложения в новой среде без портирования.

    ОтветитьУдалить
  8. Уточню, насчет встраивания ECL в апач, чтобы не думали что это химера. ECL фактически уже встраивается в апач с помощью mod_ecl.

    Т.е. задача, так же как и для mongrel2 сводится к адаптации API.

    В nginx есть втроенный перл, т.е. есть API между nginx и встроенным перлом. Можно этот же API использовать для ECL, и тогда опять же задача сводится к адаптации API.

    Короче говоря, общий API для веб программирования в Common Lisp - дело действительно достойное и назревшее.

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

    ОтветитьУдалить
  9. @Anton Vodonosov

    Кстати, если говорить о nginx и apache, то там схожая ситуация, ибо в nginx есть возможность асинхронной работы, а в apache нет. По моей задумке должен быть базовый интерфейс для синхронного исполнения плюс расширенный, для поддержки асинхронности.

    ОтветитьУдалить
  10. Это интересно. Вот такие детали я не продумывал.

    Вот что надумал я к этому моменту.

    Первую версию API хорошо сделать полностью совместимым с hunchentoot, т.е. взять какое-то подмножество hunchentoot API.

    Это позволит переносить существующие программы между серверами практически без изменений и облегчит внедрение этого API в лисп сообществе.

    Если смотреть по Function and Variable Reference в документации hunchentoot (http://www.weitz.de/hunchentoot/), то в API нужно было бы включить:

    4 Request dispatch and handling
    (часть, только самые базовые вещи.
    dispatch-table обязательно, может быть
    create-prefix-dispatcher,
    create-regex-dispatcher, хотя наверное
    нет, точно не включать define-easy-handler;
    пользователь сам решит,
    какую схему request dispatching испльзовать:
    кто-то захочет define-easy-handler, кто-то
    cl-routes, кто-то напишет что-то свое.
    Кстати, для ориентира как раз и смотреть,
    какое подмножество использует cl-routes)

    5 Request objects

    6 Reply objects

    7 Sessions

    8 Customizing session behaviour
    (все, почти все?)

    9 Cookies

    11 Conditions and error handling
    (часть?)

    12 Miscellaneous
    (часть: redirect и url-encode
    точно надо, а *cleanup-interval*,
    *cleanup-function* точно на надо)

    Остальная часть hunchentoot API (acceptors, taskmasters, logging, и т.д.) это не интерфейс меду веб приложением и веб сервером,
    а интерфейс конфигурирования и запуска самого веб сервера. На других серверах он будет свой (в google app engine особенно сильно отличаться будет).

    Было бы хорошо, определиться с набором функций и вынести в отдельный пакет, например cl-web или что-нибудь в этом роде.

    Потом было бы очень хорошо, если бы hunchentoot разработчики поддержали эту инициативу и чтобы hunchentoot перешел на использование этого пакета. Т.е. чтобы не экспортировал эти символы из пакета hunchentoot, а использовал новый пакет.

    Тогда лисп веб приложения стали бы портируемыми между разными серверами.

    А дальше можно было бы исследовать варианты реализации этого API под другими серверами, написания лисп серверов, и пути расширения этого API.

    Как вы это прокомментируете? Каких сложностей я не заметил?

    Конечно, выделение и формулирование API лучше всего делать методом "разведки боем", т.е. реализовать его под каким-то другим сервером.

    Идея с mongrel2 мне нравится больше всего. Каждый из вариантов, которые я предлагал заточены только под один лисп (ecl либо abcl).

    Интересно, что hunchentoot начинался именно
    как лисп адаптер к фронтэндам вроде mod_lisp и другим, и только со временем, когда оказалось
    что он содержит _почти_ все компоненты нужные для целого веб сервера, Edi Weitz решил добавить недостающие части.

    http://www.weitz.de/hunchentoot/#history

    ОтветитьУдалить
  11. @Anton Vodonosov

    Пока ты это писал, я это уже сделал: https://github.com/archimag/cl-wsal )) Как раз обдумал что в рассылку Hunchentoot написать ))

    ОтветитьУдалить
  12. Ух ты, вот это круто. Хотел бы я так же быстро переходить от идей к реализации, а то они у меня в голове роятся и создают избыточное давление изнутри.

    ОтветитьУдалить
  13. Значит мелких несовместимостей не избежать. Condition в hunchentoot в hunchentoot включали слово hunchentoot и пришлось переименовать (huncentoot-error -> wsal-error).

    Кстати, опечатка в названии файла - know-words.lisp (knowN имелось в виду)

    ОтветитьУдалить
  14. @Anton Vodonosov

    Не, совсем совместимость не получится. Но если Edi согласится использовать такой слой (в чём я, правда, сомневаюсь), то это не будет проблемой. В конце концов, Hunchentoot и так часто нарушает совместимость от версии версии.

    Но тут же есть другой путь. Не обязательно юзать это внутри Hunchentoot, можно сделать обёртку над Hunchentoot путём определения интерфейсов из protocol.lisp.

    > know-words.lisp

    Да, точно, спасибо. Кстати, этот файл пришлось выдергивать аж из chunga.

    ОтветитьУдалить
  15. Они так где-то используются, для перевода строк в в keywords. Я добивался того, что бы этот код компилировался и тянул всё, что надо.

    ОтветитьУдалить
  16. Покурить ))

    Тут два плана: писать в рассылу и делать Mongrel2 с этим интерфейсом.

    ОтветитьУдалить
  17. @Anton Vodonosov

    Вообщем, решил ничего пока никуда не писать, а делать Mongrel2. Как заработает как-нибудь прилично - тогда можно будет разговаривать. Заодно и опробую всё в боевых условиях.

    ОтветитьУдалить
  18. Так а что насчет времени? Времени же у вас мало? Может там тоже люди заинтересованные найдутся и подключатся.

    Alkhimov, linkfly и Rigidus будут участвовать?

    Сам я, если реально смотреть на вещи, к сожалению, не смогу участвовать, и так уже слишком много вещей одновременно делаю.

    Я думал попробовать предложить такой проект для google summer of code, т.е. чтобы какой-то студент летом этим занимался, но раз вы уже этим заниматься стали, есть ли смысл предлагать это?

    (Положительное в этом, что можно еще одного человека подключить на лето. Но это и некоторые дополнительные заботы: но нужно студент толковый нашелся, чтобы google проект утвердил, чтобы кто-то этим студентом руководил)

    Так же я думал написать автору mod_ecl, он тоже может интересоваться этим. А если так, то и в ECL лист можно было бы написать.

    ОтветитьУдалить
  19. @Anton Vodonosov

    Давай на ты? ;)

    Задача отделения общей части Hunchentoot достаточно простая, просто бери и копируй в отдельный проект. Я сейчас это и делаю попутно.

    Сложность может быть в реализации интерфейса для конкретного сервера (там в Hunchentoot местами довольно запутанный код). Но и то.

    Вообще, у меня в результате обсуждения здесь окончательно всё сложилось (нужен был небольшой толчок) и я начал писать. К лету в этой части вряд ли что останется ) Появятся другие вопросы, например, по Mongrel2 надо продумывать Taskmaster и всякие там асинхронные вещи, а также веб-сокеты и т.п. Но я ещё х.з.

    Кстати, по mod_ecl вообще мне стало интересно. Там нет таких проблем, как с Mongrel2 (ибо у Apache уже есть Taskmaster), можно было бы достаточно просто всё это прикрутить (я под Apache и на C писать могу, писал когда-то) и запустить RESTAS для него.

    Поскольку я начал писать (главное начать), то какая нужна помощью по коду я пока не знаю, пока пишу )) А вот помощь с общением и "пропагандой" может быть была бы очень кстати. Тем более, что на английском я пишу с трудом. Т.е. поднять этот вопрос в рассылках Hunchentoot и mod_ecl было бы интересно, это да.

    ОтветитьУдалить
  20. Ок, на ты удобнее :)

    Какой Taskmaster имеется в виду? Я предполагаю что это компонент по функциям такой-же как Taskmaster в hunchentoot. (Просто я не знаю
    API Mongrel2, да и сам tasmaster в hunchentoot размыто представляю, что он решает кто запрос будет обрабатывать; не уловил почему в Mongrel2 надо будет это писать, а в apache не надо).

    mod_ecl я не использовал, он недавно появился и я просто видел новость про него. Все-таки минус, это что только ECL поддерживается, который хоть и хороший лисп, но у других есть свои преимущества.

    С Mongrel Common Lisp веб станет как-то более модным :)

    Хотя одно другому не мешает. Я сегодня вечером напишу в рассылки, где эта идея может быть интересна.

    ОтветитьУдалить
  21. Taskmaster в Hunchentoot решает как рулить запросами: в одном потоке, либо поток на соединение, либо ещё как. Mongrel2 же просто посылает сообщения по ZMQ и принимает их, всё асинхронно, что там делает конкретный обработчик ему всё равно, так что функционал Taskmaster для Mongrel2 надо реализовывать самостоятельно и как это делать наиболее эффективным образом ещё вопрос (ибо простейшая схема поток на соединение значительно обесценивает преимущества Mongrel2).

    В Apache же модуль вызывается синхронно и такого вопроса вообще не стоит. Будет ли запрос обрабатываться в потоке или в отдельном процессе решает сам Apache и это зависит от его настроек и сборки.

    ОтветитьУдалить
  22. Мне кажется thread pool сделать и все. Довольно просто, и можно регулировать нагрузку. А что тут еще придумать не знаю. Только если экзотическое что-то.

    ОтветитьУдалить
  23. Не, thread pool это не модно ) Модно асинхронная обработка, как в Node.JS. Для CL сейчас правда нет библиотек нужных, но это уже вопрос второй.

    Т.е. скажем надо сделать запрос к базе, в Node.JS делаешь запрос и указываешь callback, который надо выполнить по выполнению запроса. И библиотеки для работы с базами реально асинхронные. Это даёт возможность обрабатывать большое количество запросов в малом количестве потоков, не тратя лишних системных ресурсов.

    ОтветитьУдалить
  24. Написал в hunchentoot рассылку.

    Я не готов обсуждать решения основанные на асинхронном IO и callbacks, для этого мне сначала лучше ознакомиться с Node.JS и тому подобными.

    Но во всяком случае, хоть в апач вопрос таскмастера не стоит, собственный "taskmaster" apache таких возможностей не предоставит. Поэтому больших преимуществ по сравнению с простой реализацией для Mongrel2 апач не даст.

    Псокольку ты все равно собираешься первым шагом портировать API hunchentoot один к одному, а поддержку асинхронной работы отложить и релизовать в расширенном интерфейсе, можно пока остановиться на простом таск мастере для Mongrel2.

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