Bundler - bundle package永远需要特定的gem

时间:2013-07-30 20:59:04

标签: ruby performance gem bundler

在我工作的地方,我们开发了几个Ruby Gems供内部使用。它们都依赖于我们自己的内部宝石以及RubyGems.org的第三方宝石的各种组合。

当我们使用构建服务器(ElectricCommander)进行更改时,我们会自动构建我们的gem,它将它们打包为gems并将它们存储在内部存储库中。作为该流程的一部分,我们运行bundle package --all。直到上周,我们所有的宝石一直在完美运作。

上周,我们的一个宝石开始花费超过1小时来运行bundle package命令。它运行成功,但它只需要一个多小时才能完成,这有点荒谬。

在我们的其他gem构建中,bundle package命令可以在更合适的时间内运行。每个gem包含的依赖项数量没有太大差异。它们都建立在相同的环境中。

我们正在把头发拉过来。谷歌搜索没有透露任何有同样问题的人。有没有人遇到过这个问题,或者有人知道可能导致这个问题的原因吗?

2 个答案:

答案 0 :(得分:2)

我有一个类似的问题,之前有问题的宝石依赖于另一个宝石,它有许多版本,并有许多其他依赖项。在我们的gem中,我们将另一个gem(它是rails)作为依赖,而不依赖于特定的版本。

所以我们有:

s.add_runtime_dependency "rails"

当我们添加版本时,我们看到捆绑速度显着增加:

s.add_runtime_dependency "rails", "~>3.2"

绝对严格的版本更快:

s.add_runtime_dependency "rails", "3.2.14"

我认为,缓慢的原因在于它会查看与gemspec中的依赖项匹配的所有gem版本的所有依赖项。正如您可以想象的那样,宝石已经存在了一段时间并且本身还有许多其他依赖关系,这可能会有相当多的环顾四周。

答案 1 :(得分:2)

Bundler非常努力地找到一组符合你所有捆绑要求的宝石,但在某些情况下,这种搜索可能需要很长时间。根据Gemfile中宝石的顺序,您提供的约束以及其他宝石中遇到的依赖关系,Bundler可能需要回溯解决过程并重新解析一些宝石。在最坏的情况下,这可能需要指数时间。

Pat Shaughnessy在How does Bundler bundle?中很好地解释了这个过程。正如他所提到的,在环境中使用DEBUG_RESOLVER=1运行Bundler可以帮助您了解正在发生的事情。

您可以通过改变Gemfile中Gem的顺序或使用Shadwell建议的更具体的版本约束来解决这些问题。