Пользователь
0,0
рейтинг
20 июня 2013 в 21:19

Разработка → Yesod = Haskell $ Web

Haskell — пока еще единственный язык программирования, в котором есть оператор «фтопку» (>>=)

Абсурдопедия


Планировал начать с описания того, как ошибаются люди, полагающие Haskell бесполезным с практической точки зрения, сферическим языком в вакууме и т.д. Но, боюсь, за меня все уже сделали авторы Real World Haskell. Была идея рассказать о том, насколько красив и могуч этот язык программирования — но подвел тяжелый слог и неумение придумать захватывающий сюжет с неожиданной развязкой. Поэтому отброшу все лишнее и расскажу о своих злоключениях веб-разработки на Haskell.


Действующие лица


Давно хотелось попробовать Haskell для разработки в web. Во-первых — это достаточно близко к моей профессиональной деятельности, во-вторых — это дико интересно) Ну и в итоге получаем способ изучить Haskell и не заснуть за алгоритмами сортировки и поиска факториалов.

Благо, для данного замысла существует куча готовых фреймворков (см. здесь) и необходимых пакетов (впрочем, их существуют неведомые горы для всего).
В сухом остатке, я выбрал Yesod Web Framework. Хотя он достаточно распространен и обладает хорошим функционалом, признаюсь, выбор был совершен методом научного тыка и малообоснован логически.
Помимо этого, хотелось иметь возможность не только поглядеть на результаты своего труда локально, но и похвастаться перед коллегами. Поэтому было задумано опубликовать результаты на Heroku. Для этого потребуется haskell buildpack, например этот (хотя, заранее сообщу, что в моем случае заработал только он))

Yesod


Я постараюсь описать все достаточно подробно и полно — на всякий случай. Итак, для начала потребуется установить Glasgow Haskell Compiler. Любым пакетным менеджером:

emerge -av ghc

Не помешает также cabal:

emerge -av cabal
cabal update

Для того, чтобы не ломать голову над зависимостями, стоит использовать cabal-dev, который позволит устанавливать все необходимые в дальнейшем пакеты в sandbox (похоже на virtualenv).

cabal install cabal-dev

Теперь создадим заготовку для первого приложения. Собственно, за нас все сделает yesod:

yesod init

Указываем название приложения, способ хранения данных (например, в postgresql) и вуаля — получаем директорию с вполне функционирующим веб-приложением. Осталось только установить зависимости с помощью cabal-dev:

cd MyApp
cabal-dev install

Немного медитации на консольный выхлоп — и мы на шаг ближе к реализации задумки. Осталось не забыть указать конфигурацию для бд. Ее можно увидеть в файле config/postgresql.yml — и здесь уже все украдено до нас продумано за нас! В файле присутствуют 4 вида конфигураций (development, testing, staging, production) и конфигурация по умолчанию, от которой все наследуются. Осталось указать имя пользователя бд, пароль и название базы.
Теперь запустим сервер:

yesod devel --dev

Опция --dev сообщает, что необходимо использовать cabal-dev — иначе Yesod будет искать пакеты, установленные в системе.
Все, можно, затаив дыхание, открыть в браузере http://localhost:3000 и насладиться пусть достаточно простым, но уже результатом.

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

cabal-dev build / yesod build

или просто перезапустить development сервер — нужно еще и заново установить приложение

cabal-dev install

Мне кажется это ни разу не очевидным, хотя пока не ясно баг это или фича.

Heroku


Следующий эпизод будет посвящен публикации полученного веб-приложения на Heroku. Вся эта затея возможна благодаря runtime stack под названием Cedar. При использовании этого стека, поддержка различных языков и фреймворков полностью ложится на плечи buildpack'ов, которые подготавливают окружение для запуска приложения.
Heroku поддерживает несколько таких buildpacks, например, для Ruby (ну кто бы сомневался), Node.js, Python и т.д. Помимо этого списка есть знатное количество сторонних buildpacks .
Естесственно, нам нужен таковой для Haskell, который находится без особого труда в указанном выше списке. Причем находится к моему удивлению, т.к. я обнаружил это совсем недавно, а еще некоторое время назад его там не было. На тот момент это сподвигло меня на поиск по github и перебор нескольких репозиториев, среди которых в моих руках заработал этот.

Итак, создаем приложение на heroku:

heroku create my-app --stack=cedar --buildpack https://github.com/<путь к выбранному buildpack>.git

Далее надо инициализировать git репозиторий и добавить в него MyApp. Перед деплоем необходимо внести некоторые изменения, про которые легко можно забыть. Для начала, надо перенести Procfile из директории deploy в корень проекта — в этом файле содержится информация о том, как запустить проект. После стоит поправить production конфигурацию бд и сайта:
  • approot из config/settings.yml должен указывать на итоговый url приложения (для загрузки статики, например, «my-app.herokuapp.com»)
  • user, password и т.д. из config/postgresql.yml должны содержать реальные данные heroku

По поводу бд — естесственно, для начала необходимо добавить add-on Heroku Postgres. После добавления можно узнать строку подключения командой

heroku pg:info #получаем HEROKU_POSTGRESQL_URL
heroku pg:credentials HEROKU_POSTGRESQL_URL

После комита всех произведенных изменений, указываем удаленный репозиторий heroku:

heroku git:remote -a MyApp

и отправляем изменения на сервер

git push heroku master

Ждем… Перед деплоем с помощью buildpack'а будет подготовлено окружение, будут установлены все зависимости и т.д.
И вот здесь может возникнуть проблема, которая заставляет задуматься. Дело в том, что heroku устанавливает ограничение, которое может не позволить завершить деплой. В попытках выяснить, как и почему, я клонировал репозиторий buildpack'а и осмотрел его. Подопытный напрашивался на эксперименты. Чтобы иметь возможность использовать buildpack локально и, соответственно, сразу видеть результаты всех модификаций, можно воспользоваться плагином heroku push. В этом случае деплой проекта будем производить минуя git:

heroku push -b ~/mybuildpack

После внесения некоторых изменений:

-export PATH=$FIXED_HOME/ghc/bin:$FIXED_HOME/.cabal/bin$PATH
+export PATH=$FIXED_HOME/ghc/bin:$FIXED_HOME/.cabal/bin:$PATH

-cabal install -j5 --disable-library-profiling --disable-executable-profiling --disable-shared
+cabal install -j2 --disable-library-profiling --disable-executable-profiling


к моему удивлению, все заработало и деплой прошел успешно! (бурное обсуждение в комментах поощряется, т.к. я сам доконца не понял, почему это сработало)

Заключение


Yesod — интересный и конкурентноспособный фреймворк, который обладает большим набором возможностей. Любопытно посмотреть на Yesod vs Django. До этого меня останавливал только тот факт, что никто из облачных сервисов вроде GAE, OpenShift и т.д. не собираются иметь дело с Haskell. Ну а раз проблема исчерпана, то можно и даже нужно порадовать себя изучением еще одной интересной штуки. Надеюсь, я не одинок в своих порывах)
В дальнейшем постараюсь рассказать о том, как работает и устроен Yesod. Будет много Шекспира и других плюшек)

P.S.:
Пара презентаций об использовании Haskell в production
mth.io/talks/haskell-in-production
www.shimweasel.com/hs_gbu
erthalion @erthalion
карма
25,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (24)

  • +6
    Таки рекомендую ознакомиться с happstack — в нем благородная Хаскель-стайл архитектура, а не слизанная с Ruby on Rails. А статья все равно годная :3
  • +12
    А примеров кода не будет, да?
    • 0
      Будут, но чуть позже — я постараюсь собрать силы на второй пост, в котором будет рассказано о Yesod на примерах.
  • +2
    Scotty тоже вполне ничего (hs-вариант синатры).
  • +3
    [зануда]Позвольте придраться к эпиграфу: в Haskell, насколько мне известно, можно определять свои операторы и оператор >>= определен не в самом языке, а в его библиотеке. К тому же в F# тоже можно такой оператор объявить.[/зануда]
    • +1
      да и в любом C-подобном языке он есть
  • +1
    До этого меня останавливал только тот факт, что никто из облачных сервисов вроде GAE, OpenShift и т.д. не собираются иметь дело с Haskell.


    В OpenShift можно использовать DIY картридж и установить ghc, cabal, etc. через комит-хуки. Или создать свой картридж для хаскеля, чтоб и другие смогли им пользоватся
  • –8
    Хаскель в продакшн? Не смешите!
    • +1
      • –2
        И чего? Я тоже сам для себя могу писать на чем угодно. Но это ничего не доказывает.
        • 0
          По ссылке приведены примеры реального промышленного программирования на Haskell. Каких доказательств вы ждете?
          • 0
            Обежемой, луцент моделирует что-то там для себя на хаскеле. Банки примерно тем же самым занимаются. АСИКи/ФПГА туда же. И где хоть одна система, отказ которой будет стоить $1M в час? А математику в оффлайне много на чем можно считать.
            • +2
              Ошибки в АСИКе очень дорого стоят (если ничего не путаю, подготовка к производству минимум $50k + куча времени).

              В моем проекте за год онлайна не было ни одной проблемы, связанной с хаскеллом. Зато были со всеми остальными «надежными и проверенными» подсистемами.
              • 0
                Означает ли это, что все проблемы с другими программами на хаскел исключительно по вине сторонних факторов? И конечно же можно очень легко дома самому переписать какой-нибудь хмонад так, что бы избавить его от спейс ликов. Но только вот что-то никто этого не делает…
                • +2
                  Нет, не означает. Проблемы с программами на хаскелле обычно связаны с логическими ошибками, неправильным подходом к решению задачи, плохими алгоритмами.

                  А вот проблем, чтобы бояться запустить в продакшн (segmentation fault, NullPointerException или нестабильность рантайма), нет.

                  За все время поймал только один segmentation fault (когда обрабатывал слишком много исключений типа StackOverflow, по вине логической ошибки), который был исправлен разработчиками GHC через несколько дней. Еще была фрагментация памяти, замедляющая работу в разы, но это лечится тем, что не используются долгоживущие ByteString-и.

                  Не знаю, что там за проблемы со спейс ликами в xmonad. Надо скомпилировать его с heap profiling и посмотреть, где утечка. Дело нехитрое.
                  • 0
                    Гоняю xmonad на Ubuntu 13.04 amd64, утечек замечено не было.
                • 0
                  Безмерно удивлен — за длительное время использование xmonad на Ubuntu и Gentoo не заметил проблем с утечками. Вы уверены в своем высказывании или это была метафора?)
                  • 0
                    Уверен. Иначе бы я так и пользовался хмонадой, а не перешел бы на и3, который в разы стабильнее.
            • 0
              АСИКи/ФПГА туда же.

              Очевидно, вы некомпетентны в этой области. За сим дискуссию прекращаю.
              • 0
                Что же у такого компетентного не нашлось развернутых аргументов кроме сохлой ссылки о том, что кто-то где-то вроде как может быть хаскелл и использует?
  • +3
    Забыли рассказать как yesod поставить.
    • 0
      cabal install yesod-platform
      • 0
        Жаль его нельзя сразу в cabal-dev загнать…
  • 0
    Снойман, конечно, молодец, что тащит такой функциональный фреймворк на себе, но на мой взгляд собственный синтаксис для CSS и Javascript — это перебор (я имею в виду Cassius, Julius и т.п. штуки в Yesod).

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.