Искать, найти и не сдуваться

    Друзья, хотим рассказать вам про наш сервис ШДМка.рф и некоторые детали его изготовления. Под катом статья про воздушные шары, CouchDB, Lisp и пара картинок.
    КДПВ
    На носу праздники и, быть может, кто-то из вас найдет себе идею для подарка.

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

    Сегодня из воздушных шаров делается неимоверное количество красивых штук. Проводятся фестивали и просто интересные мероприятия.

    Мы сделали сайт-каталог аэродизайнеров (а постепенно оформителей стали называться именно так), причем главное на сайте — это фотографии работ аэродизайнеров. От других сайтов-каталогов мы отличаемся наличием блокнота, который простой пользователь наполняет и отправляет дизайнеру в своем городе/регионе. Дизайнер, впрочем, тоже может отправить клиенту письмо с наполненным блокнотом.



    Расскажу о технической составляющей сайта, поскольку в процессе разработки было найдено несколько интересных вещей, или слабо описанных в документации, или это описание приходилось собирать по крупицам на форумах.

    Lisp


    Сайт написан на языке Common Lisp (в реализации SBCL). Выбор языка обусловлен удобством кодирования и большим количеством библиотек. Под свои нужды были подправлены всего две библиотеки, причем весьма незначительно, остальное заработало «из коробки».

    Код сайта компилируется сразу в машинный код, соответственно производительность сайта получается высокой. Хочется верить, что это утверждение выдержит проверку хабраэффектом :)

    CouchDB


    В качестве хранилища данных используется CouchDB. В ней хранятся фотографии и миниатюры к ним, а также информация о пользователях.

    CouchDB включает в себя довольно удобную среду управления данными Futon, у которой есть один недостаток — весь код на JS, который используется для управления БД (views, list functions и т.д.), сериализуется в строку и его практически невозможно править в самой среде.

    Для решения этой проблемы используется утилита couchapp.

    CouchApp

    Это небольшая утилита на python, которая позволяет создавать самостоятельные (standalone) приложения на CouchDB. Утилита по шаблону генерирует код приложения и, что самое важное, позволяет одной командой производить загрузку приложения в CouchDB. При этом само приложение имеет в файловой системе древовидную структуру, где в разных папках лежит код разных элементов, например представлений или вспомогательный код. В нормальном для человека виде.

    Кроме того, утилита позволяет по мере разработки добавлять разные элементы couchapp-приложения — представления, списки и т.д.

    Например так:

    couchapp generate view check-user
    

    Здесь check-user — это название сгенерированного представления. Утилита создает каталог views/check-user, в котором будут шаблоны для map- и reduce-функций.

    Update-функции

    Поскольку в CouchDB данные никогда не перезаписываются, а только добавляются в БД, очень важным элементом работы является наличие ревизии документа. Почти любое обращение к документу на запись требует знание ревизии документа. Это не всегда удобно.

    В CouchDB есть функции обновления (update functions), которые позволяют манипулировать документами на стороне сервера (не сгружая их на клиента), не зная их ревизию. В документации этот момент описан как-то довольно скромно, вместе с тем, функции обновления позволяют делать интересные вещи:

    function(doc, req) {
      if (!doc) {
        doc = {
          _id: req.id,
          type: 'idGenerator',
          count: 0
        };
      }
      doc.count++;
      return [doc, '"' + doc.count + '"'];
    }
    

    Приведенный фрагмент кода на каждый вызов фукнции увеличивается поле count документа. Таким образом реализован генератор последовательных номеров на CouchDB.
    Вызов функции, к слову, производится следующим образом:

    curl -X POST http://localhost:5984/database/_design/view-doc/_update/generateOrderNo/counterDoc
    

    Здесь view-doc — это design document в БД database, generateOrderNo — update function, counterDoc — документ в БД database.

    Вызывая приведенную функцию мы каждый раз инкрементируем поле в документе и сразу же получаем значение этого номера. Аналог поля с автоинкрементом для SQL.

    CouchApp, правда, не умеет генерировать update functions, однако, если вручную создать каталог updates и поместить в него функцию указанного выше содержания, то приложение спокойно загружается в CouchDB.

    Подстановка кода

    В CouchDB нет возможности в функциях представлений использовать какой-бы то ни было библиотечный код. Эту проблему CouchApp решает весьма, на мой взгляд, элегантно.

    Можно указать в коде map-функции (или reduce-функции) конструкцию

    function (doc) {
    ...
    // !code vendor/myapp/common.js
    ...
    }
    

    и в то место в коде, где эта строка встречается, будет вставлено содержимое файла common.js, расположенного в соответствующей папке приложения. Пусть и не самое красивое решение, но оно позволяет общий код писать один раз.

    Фреймворк


    В качестве основы для интерфейса был выбран фреймворк Ink. Он имеет интересную внутреннюю структуру и развитый функционал. Кроме того, фреймворк довольно быстро развивается.

    Заключение


    В общем и целом, когда хочется праздника, вспомните о воздушных шарах. Особенно, в пятницу четверг вечером перед праздником.

    Ну а аэродизайнеров, которые могут устроить этот праздник, можно найти на нашем сайте. На главной есть ссылка на страницу с дизайнерами из вашего региона. Если окажется, что там никого нет, можете нажать кнопочку «Хочу, чтобы были!» и мы будем приглашать аэродизайнеров из ваших городов ссылаясь на вашу заинтересованность.

    На картинке для привлечения внимания маскот FreeBSD, выполненный из воздушных шаров, логотип CouchDB и один из логотипов Lisp, выполненный на кофе.



    Напоследок несколько ссылок предпраздничного характера:

    Маскот FreeBSD из шаров
    Geeklatte.com, ИТ-рисунки на кофе

    Спасибо за внимание!

    Критика и пожелания приветствуются.
    • –1
    • 2.8k
    • 8
    Share post

    Comments 8

      +4
      Не очень понятно, какие выгоды от использования couchdb и lisp вы получили. Подозреваю, что только головную боль.
        0
        Такая связка показала себя очень эффективной и удобной на предыдущем проекте и мигрировала в этот.
          0
          А в чем выгода хранить бинарные изображения в CouchDB?
            0
            Ну это довольно удобно.
            Блобы, лежащие в том же документе, что и другие данные, удобно получать и использовать.
            Получаешь из БД документ и сразу все ссылки на вложения.
        0
        Праздник в четверг вечером выглядит вот так? ))

        image
          0
          Хех, да :)
            –1
            Реквестирую серию постов про вебдев на common lisp. Работа с БД, логирование, чтение конфигов, REST-интерфейс, затем прикручивание шаблонизатора.
              +1
              Ваша заявка принята :)
              Такие планы есть, правда пока без конкретных сроков.

            Only users with full accounts can post comments. Log in, please.