什么是最好的Haskell库来使程序可运行?[关闭]


115

如果我要将某个程序投入生产,则需要将该程序做几件事才能使其“可操作”-即,工程师和操作人员都可以以一种可测量且可验证的方式来运行和维护该程序。出于我的目的,已实施的程序必须:

  • 能够登录多个级别(例如:调试,警告等)。
  • 能够收集和共享有关程序正在执行的工作类型以及该工作需要花费多长时间的度量标准/统计信息。理想情况下,收集的度量可以以与常用的监视工具(例如Ganglia)兼容的格式使用,或者可以被忽略。
  • 是可配置的,理想情况下是通过这样的系统进行的:该系统允许更新正在运行的程序中配置的属性,而无需重新启动所述程序。
  • 可重复地部署到远程服务器。

在Scala世界中,有很好的库可以处理至少前三个需求。例子:

至于部署,在Scala世界中采取的一种方法是将组成程序的字节码和库与assembly-sbt等捆绑在一起,然后使用Capistrano之类的工具将生成的捆绑(“胖JAR”)推送到远程服务器通过SSH并行执行命令。这不是必须使用特定于语言的工具的问题,但是我很好奇Haskell社区中是否存在这样的工具。

可能有Haskell库提供了我上面描述的特征。我想知道哪些可用的库被认为是“最好的”;也就是说,这是Haskell社区中常用的最成熟,维护最完善的示例,并且是Haskell最佳做法的典范。

如果还有其他使Haskell代码“投入生产”的库,工具或实践,我也很想知道这些。


1
第四个项目符号可能会引起麻烦,因为Haskell已编译为本地代码。您可以尝试进行静态编译,这可能会或可能不会起作用,但是最理想的情况是,生产服务器上的环境应与开发服务器上的环境类似。Cabal-dev是沙盒环境,可能适合转移到其他计算机。即使这样,它也至少需要将基本库安装在目标计算机上。
Masse

1
至于其他的工具和技术,这太问题有一个概述:stackoverflow.com/questions/3077866/...
唐·斯图尔特

1
另一件事-您可以直接通过/ proc文件系统在* nix系统上访问大量进程统计信息和元数据。因此,如果您编写一些例程来进行内省,这将有助于替代运行时缺少直接挂钩的情况。
sclv 2011年

1
只要在相同的环境上构建,部署二进制文件就很容易(如果您的计算机是不同的体系结构,则应该拥有一个登台服务器)。然后,您可以rsync二进制文件和任何外部文件。haskell没有用于自动执行重启命令的ssh库,但是您可以使用capistrano。
格雷格·韦伯

1
@tchrist他将第一段的其余部分和项目符号列表都花在紧随其后的可操作词后面,用普通英语解释其含义。
Will McCutchen

Answers:


54

这是一个很好的问题!这是第一道菜。

能够登录多个级别(例如:调试,警告等)。

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和线程行为。

类似的标记可用于增量的,记录的时间空间分析,可用于监视(例如,这些可以增量构建)。

hpc通过Tix类型收集了有关程序执行的大量统计信息,人们编写了工具来按时间片记录正在执行的代码。

是可配置的,理想情况下是通过这样的系统进行的:该系统允许更新正在运行的程序中配置的属性,而无需重新启动所述程序。

有几种工具可用于此目的,您可以执行xmonad样式的状态重新加载;或通过plugins*软件包或进入代码热交换hint。其中一些比其他更具实验性。

可复制的部署

Galois最近发布了cabal-dev,它是用于进行可复制构建的工具(即,对范围进行了限定和控制)。


6
dyre软件包应该抽象出xmonad风格的状态重载,因此,我认为应该特别提及。但是,它将重新编译和重新部署联系在一起,因此真正意义上的是对带有整个工具链的机器的更改。对于远程重新部署,您需要更像酸性状态的东西,尽管它对我的口味有点沉重。我已经有了这种持久性的mvar抽象,它具有较弱的保证,但是您可以将其视为普通的MVar,它在每次启动二进制文件时都神奇地填充了保存的最新数据。
sclv 2011年

2
此外,GHC的新EventLog日志记录框架(+RTS -l在运行时使用)将输出流传输到文件,可以使用任何读取事件日志格式的工具将其可视化。
唐·斯图尔特

2
程序将发出其事件的日志,例如:galois.com/~dons/tmp/A.event.log- 可以形象化为-i.imgur.com/QAe6r.png。我可以想象在此格式的基础上构建其他监视工具。
唐·斯图尔特

2
还要注意,许多性能分析工具非常适合测试,而对于生产代码则不太适合。除去开销,例如-prof只能与单个处理器一起使用。
sclv 2011年

9
  • 关于配置,我发现ConfigFile对我的项目很有用。我将其用于生产中的所有守护程序。它不会自动更新。
  • 我使用cabal-dev在各种环境(本地,开发,本地同事)中创建可复制的内部版本。真正的cabal-dev必不可少,尤其是因为它能够在项目目录中支持本地修补版本的库。
  • 对于它的价值,我将使用xmonad样式的状态重载。Haskell的纯度使其变得无关紧要。迁移是一个问题,但是仍然存在。我对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

9

我会回应Don所说的一切,并添加一些一般性建议。

例如,您可能要考虑另外两个工具和库:

  • 快速检查基于属性的测试
  • hlint作为的扩展版本-Wall

这些都针对代码质量。

作为编码实践,请避免使用惰性IO。如果需要流式IO,请使用iteratee库之一,例如enumerator。如果你看黑客您会看到像http-enumerator这样的库,它们对HTTP请求使用枚举器样式。

至于选择黑客库,有时可以帮助您查看有多少软件包依赖于某些东西。轻松查看您可以使用此网站的软件包的反向依赖性,该软件包反映了黑客行为:

如果您的应用程序最终执行紧密循环(例如处理许多请求的Web服务器),则惰性可能是空间泄漏的问题。通常,这是在正确的位置添加严格性注释的问题。剖析,经验和阅读核心是我所知与这种事情作斗争的主要技术。我所知道的最佳配置参考是《真实世界》 Haskell的第25章

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.