shake-build-system - 启动服务的正确方法,如果它没有使用shake-build运行?
问题描述
我的构建过程需要访问各种服务,例如 Postgres、Redis 和 ElasticSearch。以Postgres为例,我写了如下的“oracle”:
data PostgresVersion = PostgresVersion deriving (Show, Typeable, Eq, Hashable, Binary, NFData, Generic)
type instance RuleResult PostgresVersion = String
shakeArgs shakeOptions{..} $ do
want [..]
addOracle $ \PostgresVersion -> do
fromStdout <$> cmd (AddEnv "PGPASSWORD" "REDACTED") ["psql", "-qAt", "-U", "pguser", "-h", "localhost", "dbname", "-c", "show server_version"]
除了确保 Postgres 正在运行之外,它还捕获版本号,这可能是构建过程中的额外断言。
但是,如何处理 Postgres 未运行的情况?我应该使用标准的 Haskell try
/catch
来处理它并启动 Postgres 吗?或者启动/停止服务是否应该超出“Shakefile”的范围?
解决方案
答案完全取决于您想要什么结果,但听起来您希望始终确保 Postgres 可用并且在构建期间可以访问它。在这种情况下,我会利用 Shake 脚本只是 Haskell 的事实并编写:
withPostgres :: ConnectionString -> (PostgresHandle -> IO a) -> IO a
withPostgres = written without using Shake at all
然后将您定义main
为:
main = withPostgres "" $ \pg ->
shakeArgs ... using pg
唯一的缺点是即使不需要它也将始终启动 Postgres。要仅在必要时启动它,您可以将 Postgres 的启动转换为缓存操作(最多运行一次):
rules = do
startPostgres <- newCache $ \() -> do
... start Postgres here ...
runAfter $ ... shut down Postgres if you want ...
"*.txt" %> \out -> do
startPostgres ()
... now use Postgres ...
在这两种情况下,我都会利用启动 Postgres 完全在 IO 中的事实,并使用普通catch
/finally
等来处理异常。如果您在Action
monad 中,您可以使用启动 PostgresliftIO
的任何操作来运行。IO
更多信息可以在 GitHub 问题中找到,该问题涵盖了类似的领域:https ://github.com/ndmitchell/shake/issues/615
推荐阅读
- javascript - 按数组过滤对象数组
- javascript - 如何将一个类(基于 if - else 的结果)动态分配给使用 Bootstrap Tagsinput 的弹出框工具提示的 span 标签
- python - 为什么 csv 文件中的整数作为字符串读入 pandas 数据帧
- python-3.x - 在运行时加载自定义类
- bash - 运行 Azure CLI 命令的单引号问题
- r - 创建自定义时间间隔以在 r 中绘制时间序列
- python-3.x - 在 Ploty 中绘制数据框中的特定单元格
- c# - 如何以 7 十进制毫秒最大化日期时间值?
- plotly - 从颜色变量中删除字符 plotly express
- c++ - 关于 Raylib 的问题 - 如何围绕 x 轴旋转玩家?