bundler 2.0.2 → 2.1.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bundler might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +687 -574
- data/LICENSE.md +18 -19
- data/README.md +8 -7
- data/bundler.gemspec +5 -23
- data/exe/bundle +19 -3
- data/lib/bundler.rb +121 -68
- data/lib/bundler/build_metadata.rb +3 -3
- data/lib/bundler/capistrano.rb +5 -5
- data/lib/bundler/cli.rb +130 -124
- data/lib/bundler/cli/add.rb +27 -16
- data/lib/bundler/cli/common.rb +10 -11
- data/lib/bundler/cli/config.rb +161 -86
- data/lib/bundler/cli/console.rb +2 -2
- data/lib/bundler/cli/doctor.rb +4 -4
- data/lib/bundler/cli/exec.rb +4 -9
- data/lib/bundler/cli/gem.rb +5 -5
- data/lib/bundler/cli/info.rb +17 -5
- data/lib/bundler/cli/init.rb +1 -1
- data/lib/bundler/cli/install.rb +3 -3
- data/lib/bundler/cli/issue.rb +1 -1
- data/lib/bundler/cli/open.rb +10 -6
- data/lib/bundler/cli/outdated.rb +85 -81
- data/lib/bundler/cli/package.rb +8 -9
- data/lib/bundler/cli/plugin.rb +9 -2
- data/lib/bundler/cli/pristine.rb +1 -1
- data/lib/bundler/cli/show.rb +1 -1
- data/lib/bundler/cli/update.rb +32 -12
- data/lib/bundler/compact_index_client.rb +25 -9
- data/lib/bundler/compact_index_client/updater.rb +2 -6
- data/lib/bundler/current_ruby.rb +8 -7
- data/lib/bundler/definition.rb +33 -26
- data/lib/bundler/dependency.rb +16 -4
- data/lib/bundler/deployment.rb +2 -2
- data/lib/bundler/dsl.rb +18 -42
- data/lib/bundler/env.rb +6 -5
- data/lib/bundler/environment_preserver.rb +0 -1
- data/lib/bundler/feature_flag.rb +0 -12
- data/lib/bundler/fetcher.rb +14 -11
- data/lib/bundler/fetcher/compact_index.rb +26 -12
- data/lib/bundler/fetcher/dependency.rb +1 -1
- data/lib/bundler/fetcher/downloader.rb +3 -0
- data/lib/bundler/fetcher/index.rb +4 -2
- data/lib/bundler/friendly_errors.rb +4 -5
- data/lib/bundler/gem_helper.rb +8 -8
- data/lib/bundler/gem_helpers.rb +2 -4
- data/lib/bundler/gem_tasks.rb +1 -1
- data/lib/bundler/gem_version_promoter.rb +3 -3
- data/lib/bundler/graph.rb +2 -2
- data/lib/bundler/injector.rb +3 -1
- data/lib/bundler/inline.rb +19 -18
- data/lib/bundler/installer.rb +7 -14
- data/lib/bundler/installer/gem_installer.rb +5 -1
- data/lib/bundler/installer/parallel_installer.rb +4 -4
- data/lib/bundler/installer/standalone.rb +1 -2
- data/lib/bundler/lazy_specification.rb +2 -2
- data/lib/bundler/lockfile_parser.rb +13 -21
- data/lib/bundler/match_platform.rb +1 -1
- data/lib/bundler/plugin.rb +29 -18
- data/lib/bundler/plugin/api.rb +1 -1
- data/lib/bundler/plugin/api/source.rb +2 -2
- data/lib/bundler/plugin/index.rb +10 -2
- data/lib/bundler/plugin/installer.rb +28 -15
- data/lib/bundler/psyched_yaml.rb +1 -1
- data/lib/bundler/resolver.rb +72 -24
- data/lib/bundler/resolver/spec_group.rb +2 -2
- data/lib/bundler/retry.rb +2 -2
- data/lib/bundler/ruby_version.rb +4 -19
- data/lib/bundler/rubygems_ext.rb +10 -65
- data/lib/bundler/rubygems_gem_installer.rb +1 -1
- data/lib/bundler/rubygems_integration.rb +135 -403
- data/lib/bundler/runtime.rb +2 -9
- data/lib/bundler/settings.rb +15 -48
- data/lib/bundler/setup.rb +6 -5
- data/lib/bundler/shared_helpers.rb +53 -68
- data/lib/bundler/similarity_detector.rb +2 -2
- data/lib/bundler/source.rb +5 -5
- data/lib/bundler/source/git.rb +19 -12
- data/lib/bundler/source/git/git_proxy.rb +35 -39
- data/lib/bundler/source/metadata.rb +7 -2
- data/lib/bundler/source/path.rb +13 -8
- data/lib/bundler/source/rubygems.rb +11 -5
- data/lib/bundler/source/rubygems/remote.rb +1 -2
- data/lib/bundler/source_list.rb +9 -12
- data/lib/bundler/spec_set.rb +1 -6
- data/lib/bundler/stub_specification.rb +18 -30
- data/lib/bundler/templates/Executable.bundler +22 -13
- data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +3 -3
- data/lib/bundler/templates/newgem/Gemfile.tt +8 -0
- data/lib/bundler/templates/newgem/README.md.tt +4 -3
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +2 -18
- data/lib/bundler/templates/newgem/test/test_helper.rb.tt +0 -4
- data/lib/bundler/templates/newgem/travis.yml.tt +0 -1
- data/lib/bundler/ui.rb +3 -3
- data/lib/bundler/ui/rg_proxy.rb +1 -1
- data/lib/bundler/ui/shell.rb +4 -8
- data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +161 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +66 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +176 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +3 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo.rb +6 -6
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +6 -6
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +30 -8
- data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +4 -4
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +2 -2
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +248 -279
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +40 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +53 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +79 -0
- data/lib/bundler/vendor/thor/lib/thor.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +7 -7
- data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/base.rb +13 -13
- data/lib/bundler/vendor/thor/lib/thor/group.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +2 -2
- data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -4
- data/lib/bundler/vendor/thor/lib/thor/runner.rb +4 -4
- data/lib/bundler/vendor/thor/lib/thor/shell.rb +3 -3
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
- data/lib/bundler/vendored_fileutils.rb +1 -6
- data/lib/bundler/vendored_molinillo.rb +1 -1
- data/lib/bundler/vendored_persistent.rb +7 -5
- data/lib/bundler/vendored_thor.rb +2 -2
- data/lib/bundler/version.rb +1 -20
- data/lib/bundler/version_ranges.rb +51 -5
- data/lib/bundler/vlad.rb +3 -3
- data/lib/bundler/worker.rb +1 -3
- data/lib/bundler/yaml_serializer.rb +2 -3
- data/man/bundle-add.1 +10 -2
- data/man/bundle-add.1.txt +11 -5
- data/man/bundle-add.ronn +7 -1
- data/man/bundle-binstubs.1 +2 -2
- data/man/bundle-binstubs.1.txt +2 -2
- data/man/bundle-binstubs.ronn +1 -1
- data/man/bundle-check.1 +1 -1
- data/man/bundle-check.1.txt +6 -6
- data/man/bundle-clean.1 +1 -1
- data/man/bundle-clean.1.txt +1 -1
- data/man/bundle-config.1 +35 -35
- data/man/bundle-config.1.txt +65 -66
- data/man/bundle-config.ronn +41 -39
- data/man/bundle-doctor.1 +1 -1
- data/man/bundle-doctor.1.txt +1 -1
- data/man/bundle-exec.1 +1 -1
- data/man/bundle-exec.1.txt +1 -1
- data/man/bundle-gem.1 +1 -1
- data/man/bundle-gem.1.txt +3 -3
- data/man/bundle-info.1 +1 -1
- data/man/bundle-info.1.txt +1 -1
- data/man/bundle-init.1 +1 -1
- data/man/bundle-init.1.txt +1 -1
- data/man/bundle-inject.1 +1 -1
- data/man/bundle-inject.1.txt +1 -1
- data/man/bundle-install.1 +8 -5
- data/man/bundle-install.1.txt +56 -51
- data/man/bundle-install.ronn +9 -4
- data/man/bundle-list.1 +1 -1
- data/man/bundle-list.1.txt +1 -1
- data/man/bundle-lock.1 +1 -1
- data/man/bundle-lock.1.txt +16 -16
- data/man/bundle-open.1 +1 -1
- data/man/bundle-open.1.txt +1 -1
- data/man/bundle-outdated.1 +1 -1
- data/man/bundle-outdated.1.txt +1 -1
- data/man/bundle-package.1 +1 -1
- data/man/bundle-package.1.txt +1 -1
- data/man/bundle-platform.1 +1 -1
- data/man/bundle-platform.1.txt +1 -1
- data/man/bundle-pristine.1 +1 -1
- data/man/bundle-pristine.1.txt +1 -1
- data/man/bundle-remove.1 +1 -1
- data/man/bundle-remove.1.txt +1 -1
- data/man/bundle-show.1 +1 -1
- data/man/bundle-show.1.txt +1 -1
- data/man/bundle-update.1 +4 -4
- data/man/bundle-update.1.txt +64 -65
- data/man/bundle-update.ronn +3 -3
- data/man/bundle-viz.1 +1 -1
- data/man/bundle-viz.1.txt +1 -1
- data/man/bundle.1 +2 -2
- data/man/bundle.1.txt +7 -7
- data/man/bundle.ronn +1 -1
- data/man/gemfile.5 +12 -15
- data/man/gemfile.5.ronn +9 -13
- data/man/gemfile.5.txt +103 -107
- metadata +11 -112
- data/exe/bundle_ruby +0 -60
- data/lib/bundler/cli/cache.rb +0 -36
- data/lib/bundler/compatibility_guard.rb +0 -13
- data/lib/bundler/ssl_certs/.document +0 -1
- data/lib/bundler/ssl_certs/certificate_manager.rb +0 -66
- data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +0 -21
- data/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +0 -23
- data/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +0 -25
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb +0 -27
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb +0 -129
@@ -31,7 +31,7 @@ m = Module.new do
|
|
31
31
|
bundler_version = a
|
32
32
|
end
|
33
33
|
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
|
34
|
-
bundler_version = $1
|
34
|
+
bundler_version = $1
|
35
35
|
update_index = i
|
36
36
|
end
|
37
37
|
bundler_version
|
@@ -61,32 +61,41 @@ m = Module.new do
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def bundler_version
|
64
|
-
@bundler_version ||=
|
64
|
+
@bundler_version ||=
|
65
65
|
env_var_version || cli_arg_version ||
|
66
|
-
lockfile_version
|
67
|
-
|
66
|
+
lockfile_version
|
67
|
+
end
|
68
|
+
|
69
|
+
def bundler_requirement
|
70
|
+
return "#{Gem::Requirement.default}.a" unless bundler_version
|
71
|
+
|
72
|
+
bundler_gem_version = Gem::Version.new(bundler_version)
|
73
|
+
|
74
|
+
requirement = bundler_gem_version.approximate_recommendation
|
75
|
+
|
76
|
+
return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0")
|
77
|
+
|
78
|
+
requirement += ".a" if bundler_gem_version.prerelease?
|
79
|
+
|
80
|
+
requirement
|
68
81
|
end
|
69
82
|
|
70
83
|
def load_bundler!
|
71
84
|
ENV["BUNDLE_GEMFILE"] ||= gemfile
|
72
85
|
|
73
|
-
|
74
|
-
activate_bundler(bundler_version.dup)
|
86
|
+
activate_bundler
|
75
87
|
end
|
76
88
|
|
77
|
-
def activate_bundler
|
78
|
-
if Gem::Version.correct?(bundler_version) && Gem::Version.new(bundler_version).release < Gem::Version.new("2.0")
|
79
|
-
bundler_version = "< 2"
|
80
|
-
end
|
89
|
+
def activate_bundler
|
81
90
|
gem_error = activation_error_handling do
|
82
|
-
gem "bundler",
|
91
|
+
gem "bundler", bundler_requirement
|
83
92
|
end
|
84
93
|
return if gem_error.nil?
|
85
94
|
require_error = activation_error_handling do
|
86
95
|
require "bundler/version"
|
87
96
|
end
|
88
|
-
return if require_error.nil? && Gem::Requirement.new(
|
89
|
-
warn "Activating bundler (#{
|
97
|
+
return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
98
|
+
warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
|
90
99
|
exit 42
|
91
100
|
end
|
92
101
|
|
@@ -68,7 +68,7 @@ members of the project's leadership.
|
|
68
68
|
## Attribution
|
69
69
|
|
70
70
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
-
available at [
|
71
|
+
available at [https://contributor-covenant.org/version/1/4][version]
|
72
72
|
|
73
|
-
[homepage]:
|
74
|
-
[version]:
|
73
|
+
[homepage]: https://contributor-covenant.org
|
74
|
+
[version]: https://contributor-covenant.org/version/1/4/
|
@@ -2,3 +2,11 @@ source "https://rubygems.org"
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in <%= config[:name] %>.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
gem "rake", "~> 12.0"
|
7
|
+
<%- if config[:ext] -%>
|
8
|
+
gem "rake-compiler"
|
9
|
+
<%- end -%>
|
10
|
+
<%- if config[:test] -%>
|
11
|
+
gem "<%= config[:test] %>", "~> <%= config[:test_framework_version] %>"
|
12
|
+
<%- end -%>
|
@@ -14,7 +14,7 @@ gem '<%= config[:name] %>'
|
|
14
14
|
|
15
15
|
And then execute:
|
16
16
|
|
17
|
-
$ bundle
|
17
|
+
$ bundle install
|
18
18
|
|
19
19
|
Or install it yourself as:
|
20
20
|
|
@@ -32,7 +32,8 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
32
|
|
33
33
|
## Contributing
|
34
34
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/<%= config[:github_username] %>/<%= config[:name] %>.<% if config[:coc] %> This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/<%= config[:github_username] %>/<%= config[:name] %>.<% if config[:coc] %> This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/master/CODE_OF_CONDUCT.md).<% end %>
|
36
|
+
|
36
37
|
<% if config[:mit] -%>
|
37
38
|
|
38
39
|
## License
|
@@ -43,5 +44,5 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
43
44
|
|
44
45
|
## Code of Conduct
|
45
46
|
|
46
|
-
Everyone interacting in the <%= config[:constant_name] %> project
|
47
|
+
Everyone interacting in the <%= config[:constant_name] %> project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/master/CODE_OF_CONDUCT.md).
|
47
48
|
<% end -%>
|
@@ -1,12 +1,4 @@
|
|
1
|
-
|
2
|
-
# coding: utf-8
|
3
|
-
|
4
|
-
lib = File.expand_path("../lib", __FILE__)
|
5
|
-
<%- else -%>
|
6
|
-
lib = File.expand_path("lib", __dir__)
|
7
|
-
<%- end -%>
|
8
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
9
|
-
require "<%= config[:namespaced_path] %>/version"
|
1
|
+
require_relative 'lib/<%=config[:namespaced_path]%>/version'
|
10
2
|
|
11
3
|
Gem::Specification.new do |spec|
|
12
4
|
spec.name = <%= config[:name].inspect %>
|
@@ -20,6 +12,7 @@ Gem::Specification.new do |spec|
|
|
20
12
|
<%- if config[:mit] -%>
|
21
13
|
spec.license = "MIT"
|
22
14
|
<%- end -%>
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
23
16
|
|
24
17
|
spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
25
18
|
|
@@ -38,13 +31,4 @@ Gem::Specification.new do |spec|
|
|
38
31
|
<%- if config[:ext] -%>
|
39
32
|
spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"]
|
40
33
|
<%- end -%>
|
41
|
-
|
42
|
-
spec.add_development_dependency "bundler", "~> <%= config[:bundler_version] %>"
|
43
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
44
|
-
<%- if config[:ext] -%>
|
45
|
-
spec.add_development_dependency "rake-compiler"
|
46
|
-
<%- end -%>
|
47
|
-
<%- if config[:test] -%>
|
48
|
-
spec.add_development_dependency "<%= config[:test] %>", "~> <%= config[:test_framework_version] %>"
|
49
|
-
<%- end -%>
|
50
34
|
end
|
data/lib/bundler/ui.rb
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Bundler
|
4
4
|
module UI
|
5
|
-
autoload :RGProxy, "
|
6
|
-
autoload :Shell, "
|
7
|
-
autoload :Silent, "
|
5
|
+
autoload :RGProxy, File.expand_path("ui/rg_proxy", __dir__)
|
6
|
+
autoload :Shell, File.expand_path("ui/shell", __dir__)
|
7
|
+
autoload :Silent, File.expand_path("ui/silent", __dir__)
|
8
8
|
end
|
9
9
|
end
|
data/lib/bundler/ui/rg_proxy.rb
CHANGED
data/lib/bundler/ui/shell.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "../vendored_thor"
|
4
4
|
|
5
5
|
module Bundler
|
6
6
|
module UI
|
@@ -10,9 +10,7 @@ module Bundler
|
|
10
10
|
attr_writer :shell
|
11
11
|
|
12
12
|
def initialize(options = {})
|
13
|
-
|
14
|
-
Thor::Base.shell = Thor::Shell::Basic
|
15
|
-
end
|
13
|
+
Thor::Base.shell = options["no-color"] ? Thor::Shell::Basic : nil
|
16
14
|
@shell = Thor::Base.shell.new
|
17
15
|
@level = ENV["DEBUG"] ? "debug" : "info"
|
18
16
|
@warning_history = []
|
@@ -35,14 +33,12 @@ module Bundler
|
|
35
33
|
return if @warning_history.include? msg
|
36
34
|
@warning_history << msg
|
37
35
|
|
38
|
-
|
39
|
-
tell_me(msg, :yellow, newline)
|
36
|
+
tell_err(msg, :yellow, newline)
|
40
37
|
end
|
41
38
|
|
42
39
|
def error(msg, newline = nil)
|
43
40
|
return unless level("error")
|
44
|
-
|
45
|
-
tell_me(msg, :red, newline)
|
41
|
+
tell_err(msg, :red, newline)
|
46
42
|
end
|
47
43
|
|
48
44
|
def debug(msg, newline = nil)
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require_relative 'connection_pool/version'
|
2
|
+
require_relative 'connection_pool/timed_stack'
|
3
|
+
|
4
|
+
|
5
|
+
# Generic connection pool class for e.g. sharing a limited number of network connections
|
6
|
+
# among many threads. Note: Connections are lazily created.
|
7
|
+
#
|
8
|
+
# Example usage with block (faster):
|
9
|
+
#
|
10
|
+
# @pool = Bundler::ConnectionPool.new { Redis.new }
|
11
|
+
#
|
12
|
+
# @pool.with do |redis|
|
13
|
+
# redis.lpop('my-list') if redis.llen('my-list') > 0
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# Using optional timeout override (for that single invocation)
|
17
|
+
#
|
18
|
+
# @pool.with(timeout: 2.0) do |redis|
|
19
|
+
# redis.lpop('my-list') if redis.llen('my-list') > 0
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# Example usage replacing an existing connection (slower):
|
23
|
+
#
|
24
|
+
# $redis = Bundler::ConnectionPool.wrap { Redis.new }
|
25
|
+
#
|
26
|
+
# def do_work
|
27
|
+
# $redis.lpop('my-list') if $redis.llen('my-list') > 0
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# Accepts the following options:
|
31
|
+
# - :size - number of connections to pool, defaults to 5
|
32
|
+
# - :timeout - amount of time to wait for a connection if none currently available, defaults to 5 seconds
|
33
|
+
#
|
34
|
+
class Bundler::ConnectionPool
|
35
|
+
DEFAULTS = {size: 5, timeout: 5}
|
36
|
+
|
37
|
+
class Error < RuntimeError
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.wrap(options, &block)
|
41
|
+
Wrapper.new(options, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
def initialize(options = {}, &block)
|
45
|
+
raise ArgumentError, 'Connection pool requires a block' unless block
|
46
|
+
|
47
|
+
options = DEFAULTS.merge(options)
|
48
|
+
|
49
|
+
@size = options.fetch(:size)
|
50
|
+
@timeout = options.fetch(:timeout)
|
51
|
+
|
52
|
+
@available = TimedStack.new(@size, &block)
|
53
|
+
@key = :"current-#{@available.object_id}"
|
54
|
+
@key_count = :"current-#{@available.object_id}-count"
|
55
|
+
end
|
56
|
+
|
57
|
+
if Thread.respond_to?(:handle_interrupt)
|
58
|
+
|
59
|
+
# MRI
|
60
|
+
def with(options = {})
|
61
|
+
Thread.handle_interrupt(Exception => :never) do
|
62
|
+
conn = checkout(options)
|
63
|
+
begin
|
64
|
+
Thread.handle_interrupt(Exception => :immediate) do
|
65
|
+
yield conn
|
66
|
+
end
|
67
|
+
ensure
|
68
|
+
checkin
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
else
|
74
|
+
|
75
|
+
# jruby 1.7.x
|
76
|
+
def with(options = {})
|
77
|
+
conn = checkout(options)
|
78
|
+
begin
|
79
|
+
yield conn
|
80
|
+
ensure
|
81
|
+
checkin
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
def checkout(options = {})
|
88
|
+
if ::Thread.current[@key]
|
89
|
+
::Thread.current[@key_count]+= 1
|
90
|
+
::Thread.current[@key]
|
91
|
+
else
|
92
|
+
::Thread.current[@key_count]= 1
|
93
|
+
::Thread.current[@key]= @available.pop(options[:timeout] || @timeout)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def checkin
|
98
|
+
if ::Thread.current[@key]
|
99
|
+
if ::Thread.current[@key_count] == 1
|
100
|
+
@available.push(::Thread.current[@key])
|
101
|
+
::Thread.current[@key]= nil
|
102
|
+
else
|
103
|
+
::Thread.current[@key_count]-= 1
|
104
|
+
end
|
105
|
+
else
|
106
|
+
raise Bundler::ConnectionPool::Error, 'no connections are checked out'
|
107
|
+
end
|
108
|
+
|
109
|
+
nil
|
110
|
+
end
|
111
|
+
|
112
|
+
def shutdown(&block)
|
113
|
+
@available.shutdown(&block)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Size of this connection pool
|
117
|
+
def size
|
118
|
+
@size
|
119
|
+
end
|
120
|
+
|
121
|
+
# Number of pool entries available for checkout at this instant.
|
122
|
+
def available
|
123
|
+
@available.length
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
class Wrapper < ::BasicObject
|
129
|
+
METHODS = [:with, :pool_shutdown]
|
130
|
+
|
131
|
+
def initialize(options = {}, &block)
|
132
|
+
@pool = options.fetch(:pool) { ::Bundler::ConnectionPool.new(options, &block) }
|
133
|
+
end
|
134
|
+
|
135
|
+
def with(&block)
|
136
|
+
@pool.with(&block)
|
137
|
+
end
|
138
|
+
|
139
|
+
def pool_shutdown(&block)
|
140
|
+
@pool.shutdown(&block)
|
141
|
+
end
|
142
|
+
|
143
|
+
def pool_size
|
144
|
+
@pool.size
|
145
|
+
end
|
146
|
+
|
147
|
+
def pool_available
|
148
|
+
@pool.available
|
149
|
+
end
|
150
|
+
|
151
|
+
def respond_to?(id, *args)
|
152
|
+
METHODS.include?(id) || with { |c| c.respond_to?(id, *args) }
|
153
|
+
end
|
154
|
+
|
155
|
+
def method_missing(name, *args, &block)
|
156
|
+
with do |connection|
|
157
|
+
connection.send(name, *args, &block)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Global monotonic clock from Concurrent Ruby 1.0.
|
2
|
+
# Copyright (c) Jerry D'Antonio -- released under the MIT license.
|
3
|
+
# Slightly modified; used with permission.
|
4
|
+
# https://github.com/ruby-concurrency/concurrent-ruby
|
5
|
+
|
6
|
+
require 'thread'
|
7
|
+
|
8
|
+
class Bundler::ConnectionPool
|
9
|
+
|
10
|
+
class_definition = Class.new do
|
11
|
+
|
12
|
+
if defined?(Process::CLOCK_MONOTONIC)
|
13
|
+
|
14
|
+
# @!visibility private
|
15
|
+
def get_time
|
16
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
17
|
+
end
|
18
|
+
|
19
|
+
elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
20
|
+
|
21
|
+
# @!visibility private
|
22
|
+
def get_time
|
23
|
+
java.lang.System.nanoTime() / 1_000_000_000.0
|
24
|
+
end
|
25
|
+
|
26
|
+
else
|
27
|
+
|
28
|
+
# @!visibility private
|
29
|
+
def initialize
|
30
|
+
@mutex = Mutex.new
|
31
|
+
@last_time = Time.now.to_f
|
32
|
+
end
|
33
|
+
|
34
|
+
# @!visibility private
|
35
|
+
def get_time
|
36
|
+
@mutex.synchronize do
|
37
|
+
now = Time.now.to_f
|
38
|
+
if @last_time < now
|
39
|
+
@last_time = now
|
40
|
+
else # clock has moved back in time
|
41
|
+
@last_time += 0.000_001
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Clock that cannot be set and represents monotonic time since
|
50
|
+
# some unspecified starting point.
|
51
|
+
#
|
52
|
+
# @!visibility private
|
53
|
+
GLOBAL_MONOTONIC_CLOCK = class_definition.new
|
54
|
+
private_constant :GLOBAL_MONOTONIC_CLOCK
|
55
|
+
|
56
|
+
class << self
|
57
|
+
##
|
58
|
+
# Returns the current time a tracked by the application monotonic clock.
|
59
|
+
#
|
60
|
+
# @return [Float] The current monotonic time when `since` not given else
|
61
|
+
# the elapsed monotonic time between `since` and the current time
|
62
|
+
def monotonic_time
|
63
|
+
GLOBAL_MONOTONIC_CLOCK.get_time
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|