Очень рекомендую эту главу RWH. Помогает бороться с проблемой поедания O(n) памяти. Которой обусловлены почти все проблемы «производительности».
А статья классная, хоть и сумбурная. Бесточечная нотация поначалу совсем не обязательна. И не только по началу.
Других способов получше разобраться с хаскелем как я понимаю нет. После руководств совсем не понятно как всё это используется на практике. Приходится просто писать.
Не совсем. Ключевой момент на две строчки ниже — putStrLn (unlines fsContents).
Если это второе использование fsContents вырезать, то всё будет работать в константе памяти (если конечно нет других ошибок). Сборщик мусора должен всё собрать, а ленивый ввод-вывод не допустить полной загрузки содержимого файлов в память.
В хаскеле кроме чистых функций ленивость реализована в операциях ввода-вывода. Внутри merge readFile фактически начнёт читать в тот момент, когда данные потребуются. И будет читать их чанками фиксированного размера. Грубо говоря каждый чанк будет проходить обработку, записываться в writeFile и подчищаться сборщиком мусора. Если после этого на них него других ссылок, а у вас есть.
Архитектура простая, как всегда хорошо описывается модулем Types.
Запускается happstack сервер, первый обработчик это функция authorize в стеке монад ServerPartT (состояние, в котором хранится запрос и другие служебные данные хаппстека), ErrorT String.
В любой момент, если встретится ошибка, работа обработчика прерывается и клиенту показывают текст ошибки.
Если авторизация прошла успешно, в стек монад добавляется ещё одно состояние с Id сессии, распарсенным конфигом приложения и IORef ссылкой на данные сессии.
После этого обработчика переходит к функции Main.control, которая маршрутизирует дальнейшую обработку исходя из url.
Ну и вокруг всего этого навешана выдача статических файлов, откат изменений файрволла, которые блокируют доступ к веб-интерфейсу и т.п.
Форма редактирования правил и обработка параметров это отдельная история. Вот тут сильно не хватает SYB, который я пока не раскурил.
Да, надо бы ключ к зашифрованному разделу передавать по телефону. Или хотя бы часть ключа. Или хранить ключ от раздела зашифрованным более слабым ключом, который передавать по телефону.
Жарил сейчас оладьи. Когда уже почти дожарились, оставил дожариваться и отошёл на 2 минуты. Вернулся через 40 минут. На них только корочка стала чуть темнее, ничего страшного не произошло. Вот это годная еда!
> на каждую клиентскую сессию в рантайме развешивается некое дерево замыканий и продолжений, которые держат ссылки на различные объекты, не позволяя мусорщику их подчистить.
> мы не можем нарастить производительность системы добавлением нового сервера с балансировкой веб-запросов в кластере. Потому что все запросы клиента в пределах одной пользовательской сессии должны попадать на ту машину, где она была создана.
А статья классная, хоть и сумбурная. Бесточечная нотация поначалу совсем не обязательна. И не только по началу.
Других способов получше разобраться с хаскелем как я понимаю нет. После руководств совсем не понятно как всё это используется на практике. Приходится просто писать.
Не совсем. Ключевой момент на две строчки ниже — putStrLn (unlines fsContents).
Если это второе использование fsContents вырезать, то всё будет работать в константе памяти (если конечно нет других ошибок). Сборщик мусора должен всё собрать, а ленивый ввод-вывод не допустить полной загрузки содержимого файлов в память.
В хаскеле кроме чистых функций ленивость реализована в операциях ввода-вывода. Внутри merge readFile фактически начнёт читать в тот момент, когда данные потребуются. И будет читать их чанками фиксированного размера. Грубо говоря каждый чанк будет проходить обработку, записываться в writeFile и подчищаться сборщиком мусора. Если после этого на них него других ссылок, а у вас есть.
Упрощает жизнь не сильно, это явно не киллер фича. Но зато и делается очень просто.
Запускается happstack сервер, первый обработчик это функция authorize в стеке монад ServerPartT (состояние, в котором хранится запрос и другие служебные данные хаппстека), ErrorT String.
В любой момент, если встретится ошибка, работа обработчика прерывается и клиенту показывают текст ошибки.
Если авторизация прошла успешно, в стек монад добавляется ещё одно состояние с Id сессии, распарсенным конфигом приложения и IORef ссылкой на данные сессии.
После этого обработчика переходит к функции Main.control, которая маршрутизирует дальнейшую обработку исходя из url.
Ну и вокруг всего этого навешана выдача статических файлов, откат изменений файрволла, которые блокируют доступ к веб-интерфейсу и т.п.
Форма редактирования правил и обработка параметров это отдельная история. Вот тут сильно не хватает SYB, который я пока не раскурил.
Вот ссылка на весь проект на Patch-tag'e.
Не знаю какие места можно назвать интересными, проект написан на достаточно простом подмножестве хаскеля.
Опыт разработки и внедрения таких систем очень интересен.
БД, языки
Не знаю как в новых, а в старых системах сплошь и рядом delphi и ms-sql, не так ли?
> на каждую клиентскую сессию в рантайме развешивается некое дерево замыканий и продолжений, которые держат ссылки на различные объекты, не позволяя мусорщику их подчистить.
> мы не можем нарастить производительность системы добавлением нового сервера с балансировкой веб-запросов в кластере. Потому что все запросы клиента в пределах одной пользовательской сессии должны попадать на ту машину, где она была создана.
> Abuse of the Continuation monad can produce code that is impossible to understand and maintain.
Пустые строки между пунктами или отступы упростили бы чтение, сплошной текст действительно трудно читать.