Каковы лучшие библиотеки Haskell для внедрения программы?

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

  • Возможность входа на несколько уровней (например: отладка, предупреждение и т.д.).
  • Уметь собирать и делиться метриками/статистикой о типах работы, выполняемой программой, и о том, как долго эта работа выполняется. В идеале, собранные показатели доступны в формате, который совместим с обычно используемыми инструментами мониторинга, такими как Ganglia, или может быть настолько запутан.
  • Конфигурируемая конфигурация, в идеале, через систему, которая позволяет обновлять настроенные свойства в запущенных программах без перезапуска указанных программ.
  • Возможность развертывания на удаленных серверах повторяющимся способом.

В мире Scala есть хорошие библиотеки для решения, по крайней мере, первых трех требований. Примеры:

  • Logula для ведения журнала.
  • Metrics или Ostrich для сбора и показатели отчетности.
  • Configgy или Fig для конфигурации.

Для развертывания один подход, принятый в мире Scala, заключается в объединении байт-кода и библиотек, которые содержат одну программу с чем-то вроде assembly-sbt, затем нажимаем полученный пакет ( "толстый JAR" ) на удаленные серверы с помощью инструмента, такого как Capistrano, который выполняет параллельные команды над SSH. Это не проблема, которая требует языковых инструментов, но мне любопытно, существует ли такой инструмент в сообществе Haskell.

Есть, вероятно, библиотеки Haskell, которые предоставляют черты, описанные выше. Я хотел бы знать, какая из доступных библиотек считается "лучшей"; то есть, которые являются наиболее зрелыми, ухоженными, обычно используемыми в сообществе Haskell, и являются образцовыми примерами лучших практик Haskell.

Если есть какие-либо другие библиотеки, инструменты или методы, которые делают код Haskell "готовым к производству", мне бы тоже хотелось узнать об этом.

Ответ 1

Это отличный вопрос! Здесь первый разрез.

Уметь регистрироваться на нескольких уровнях (например: отладка, предупреждение и т.д.).

hslogger - самая популярная фреймворк регистрации.

Уметь собирать и делиться метриками/статистикой о типах работы, выполняемой программой, и о том, как долго эта работа выполняется. В идеальном случае собранные показатели доступны в формате, совместимом с обычно используемыми инструментами мониторинга, такими как Ganglia, или могут быть помечены таким образом.

Я не знаю каких-либо стандартизованных средств отчетности, однако извлечение отчетов из потоков +RTS -s (или через профилирование выходных флагов) было чем-то, что я делал в прошлом.

$ ./A +RTS -s
64,952 bytes allocated in the heap
1 MB total memory in use
 %GC time       0.0%  (6.1% elapsed)
 Productivity 100.0% of total user, 0.0% of total elapsed

Вы также можете получить это в машиночитаемом формате:

$ ./A +RTS -t --machine-readable

 [("bytes allocated", "64952")
 ,("num_GCs", "1")
 ,("average_bytes_used", "43784")
 ,("max_bytes_used", "43784")
 ,("num_byte_usage_samples", "1")
 ,("peak_megabytes_allocated", "1")
 ,("init_cpu_seconds", "0.00")
 ,("init_wall_seconds", "0.00")
 ,("mutator_cpu_seconds", "0.00")
 ,("mutator_wall_seconds", "0.00")
 ,("GC_cpu_seconds", "0.00")
 ,("GC_wall_seconds", "0.00")
 ]

В идеале вы можете подключиться к запущенной среде выполнения GHC через сокет и в интерактивном режиме просматривать статистику по GC, но в настоящее время это не очень просто (требуется привязка FFI к интерфейсу "rts/Stats.h" ). Вы можете подключиться к процессу, используя ThreadScope и отслеживать поведение GC и потоков.

Аналогичные флаги доступны для инкрементного, регистрируемого времени и space профилирование, которое может использоваться для мониторинга (например, эти графики могут быть построены постепенно).

hpc собирает множество статистических данных о выполнении программы с помощью своего типа Tix, а люди имеют письменные инструменты, чтобы регистрировать по времени, какой код выполняется.

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

Для этого доступны несколько инструментов, вы можете выполнить перезагрузку состояния в стиле xmonad; или перейдите к перегреву кода через plugins * пакеты или hint. Некоторые из них более экспериментальны, чем другие.

Воспроизводимые развертывания

Недавно Галуа выпустил cabal-dev, который является инструментом для воспроизведения воспроизводимых сборок (т.е. зависимости охвачены и контролируются).

Ответ 2

Я бы повторил все, что сказал Дон, и добавьте несколько общих советов.

Например, два дополнительных инструментария и библиотеки, которые вы, возможно, захотите рассмотреть:

  • QuickCheck для тестирования на основе свойств
  • hlint как расширенная версия -Wall

Те же нацелены на качество кода.

Как практика кодирования, избегайте Lazy IO. Если вам нужна потоковая запись ввода-вывода, перейдите к одной из библиотек iteratee, таких как enumerator. Если вы посмотрите на Hackage, вы увидите библиотеки, такие как http-enumerator, которые используют стиль перечисления для HTTP-запросов.

Что касается выбора библиотек для взлома, иногда это может помочь определить, сколько пакетов зависит от чего-то. Легко видеть обратные зависимости пакета, который вы можете использовать на этом веб-сайте, который отображает хакеры:

Если ваше приложение заканчивает работу с жесткими циклами, например, веб-сервером, обрабатывающим множество запросов, лень может быть проблемой в виде утечек пространства. Часто это вопрос добавления аннотаций строгости в нужные места. Профилирование, опыт и ядро ​​чтения - это основные методы, которые я знаю для борьбы с подобными вещами. Лучшая справочная информация, которую я знаю, - Глава 25 Real-World Haskell.

Ответ 3

  • Что касается конфигурации, я нашел ConfigFile полезным для моих проектов. Я использую его для всех моих демонов в производстве. Он не обновляется автоматически.
  • Я использую cabal-dev для создания воспроизводимых сборок в разных средах (локальных, dev, associate-local). На самом деле cabal-dev незаменим, особенно благодаря своей способности поддерживать локальные исправленные версии библиотек в каталоге проекта.
  • Для чего это стоит, я бы пошел с перезагрузкой состояния в стиле xmonad. Чистота Хаскелла делает это тривиальным; миграция - проблема, но это так или иначе. Я экспериментировал с hsplugins и намеком на свой IRCd, и в первом случае была проблема с временем выполнения GHC, а в последнем - ошибка сегментации. Я оставил ветки на Github для более позднего посмертного: https://github.com/chrisdone/hulk

Пример ConfigFile:

# Default options
[DEFAULT]
hostname: localhost
# Options for the first file
[file1]
location: /usr/local
user: Fred