Dmitry Grebeniuk edited this page Feb 5, 2014 · 42 revisions

Дрезина -- это такой велосипед, который ездит по рельсам. Нуфф сказал. rails

Описанное

INSTALL

На момент активной разработки смешаны кое-какие вещи. Правильно должно быть так:

  • директория tpl -- ставится вместе с дрезиной куда-то
  • директория proj -- пользовательский код, шаблоны, конфигурация
  • директория proj-build -- место, куда генерируется и где впоследствии компилируется код; вероятно должно быть поддиректорией proj, например, proj/.dresina-build

Пока всё в одном репозитории, так гораздо проще делать первые шаги. И пока оставим как есть.

Следовательно, для инсталляции необходимо склонировать репозиторий и играться в нём.

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

$ opam remote add -k hg https://bitbucket.org/gds/repo-dresina

обновить пакеты opam'а:

$ opam update

и установить то, что нужно (остальное подтянется по зависимостям):

$ opam install amall ecaml ocamldep-sorter

После этого можно собирать дрезину.

To do / Plans

  • Подумать, как быть с роутами и контролерами. Что нужно:

    • Комар заблевал от кодогенерации и грозится придумать роуты с биндами.
    • Сделать так, чтобы не-блевотное легко подключалось в нужное место обработки роутов.
    • Обработка параметров запроса ("?k=v") в роутах (брать Uri.parse_params)
    • Обработка не только get-роутов; там же: на основании заголовков определять, что дают в теле post: форму или заливку файлов.
  • Продумать, как будут дела с окружением (dev/prod).

    • Для dev-окружения -- хрень, которая будет проверять, не изменились ли исходники, при изменении запускать ребилдилку, прибивать старый процесс и запускать новый, и только потом передавать ему запрос.
    • В prod-окружении не отдавать статику -- считаем, мы за nginx. (но сделать это опциональным -- вдруг наивный смелец решится выставить дрезину голой жопой в интернеты.)
  • Придумать что-нибудь революционное для работы с формами.

    • Для этого, наверное, описать тут, чем плохо спиздить формы с тех же рельсов.
  • Параметры форм, куки и заливка файлов (посмотреть в amall, iterateees, либо в коде с прошлого рабства). Для декодирования ебанутого js-escaped utf16 есть код в iteratees точно. multipart для заливки файлов -- iteratees_http.ml / it_multipart.

  • БД

    • собственно соединение с БД
    • почесать dbi.pg на предмет человеческого dbi-подобного интерфейса; сделать интерфейс мономорфным относительно вида БД (пусть через coercions)
    • научиться применять простые миграции и следить за текущей схемой БД
    • (в мечтах любителя колупаться в camlp4) Заставить PGOcaml выдавать объекты или рекорды.
  • Шаблоны html. Брать ecaml. Текущие вопросы:

    • описать и отладить соображения по поводу @x.y.z в шаблонах, таких, чтобы @x.y.z заменялось на реальные, заранее полученные в контроллере данные из базы данных, согласно описаниям моделей и ручным данным (для хитрых случаев нужно иметь возможность вносить руками данные, которые будут доступны в шаблонах).
  • Кеширование на сервере.

    • брать последнюю дату создания/изменения объектов, протаскивать её везде, сделать комбинатор типа respond_cached сущности ответ, который по сущностям будет определять, нужно ли отдавать ответ? Тут именно с технической стороны надо сделать пиздато, так как концепции ясны.
  • Попробовать присунуть ADT в роуты и в БД. Насчёт БД будет сложно, а с роутами вроде и просто, и заебись.

  • Мелочёвка:

    • Скопипастить себе Buffer и сделать там вывод содержимого буфера через lwt, чтобы не копировать из Buffer.t в отдельную строку
    • К предыдущему: из буфера копируется в строку, из строки при write копируется в ещё один, на этот раз сишный буфер, и оттуда уже write() пишет. Надо делать на bigarray (выделять почанково) и использовать хуйню (которая в сишечке io_vec штоле), которая умеет брать кучу (char* ofs, int len) и одним системным вызовом срать в сокет из памяти. Профит: минус одно копирование данных. Bigarray -- так как можно сделать его "C-managed" без перемещений, вызываемых мусорщиком.
    • Всё, выполняющееся от роутов, будет завёрнуто в IO-монаду. Поэтому для обработки тел запросов итератами нужно будет написать функцию вида run_iteratee : iteratee char 'a -> ('a -> IO.m 'b) -> IO.m 'b, которая будет брать итерат и продолжение, кидать заданное исключение, выходить из IO-монады, обрабатывать итератом тело запроса, передавать результат в продолжение, и дальше выполняться в рамках IO.
    • ocamldep можно запускать только на изменённых файлах, но подумать ещё. Как вариант -- смотреть, какие файлы изменены, запускать ocamldep только для этих файлов, а потом руками сливать старый .depend и вывод ocamldep для новых файлов.
    • Поставить таймаут на вызов действия контроллера, сделать конфигурабельным.
    • Завершением воркеров, отслеживанием таймаутов, прибиением, обновлением воркеров на новый бинарник будет заниматься аналог юникорна. Для обновлений будет два разных сокета -- старые и новые соединения. При обновлении юникорн должен отправлять новые соединения на новый бинарник, ждать отсыхания соединений со старого бинарника и прибивать старые процессы. В воркерах не нужно дополнительной логики про завершение. А таймауты в качестве простой оптимизации -- в воркерах не лишне. На случай, если тред чисто lwt и пригоден к прибиванию.
    • Посмотреть, что можно сделать с main_{pre,post}, чтобы не склеивать его, а положиться на модульную систему.
    • ecaml: сливать фиксированные строки шаблона в один большой Buffer.add_string.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.