启动服务的正确方法,如果它没有使用 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 未运行的情况?我应该使用标准的Haskelltry/catch来处理它并启动Postgres吗?还是启动/停止服务是否应该超出"摇盘"的范围?

答案完全取决于你想要的结果,但听起来你想始终确保 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等来处理异常。如果你在Actionmonad 中,你可以使用liftIO来运行任何IO操作启动 Postgres。

更多信息可以在 GitHub 问题中找到,其中涵盖了类似的领域:https://github.com/ndmitchell/shake/issues/615

最新更新