bundler 4.0.21 → 4.1.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/{lib/bundler/vendor/connection_pool/LICENSE → MIT.txt} +8 -6
- data/bundler.gemspec +23 -6
- data/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/checksum.rb +40 -25
- data/lib/bundler/ci_detector.rb +1 -1
- data/lib/bundler/cli/add.rb +3 -4
- data/lib/bundler/cli/cache.rb +4 -0
- data/lib/bundler/cli/clean.rb +5 -0
- data/lib/bundler/cli/common.rb +37 -1
- data/lib/bundler/cli/config.rb +4 -2
- data/lib/bundler/cli/gem.rb +0 -17
- data/lib/bundler/cli/install.rb +4 -5
- data/lib/bundler/cli/lock.rb +1 -2
- data/lib/bundler/cli/outdated.rb +8 -3
- data/lib/bundler/cli/pristine.rb +2 -1
- data/lib/bundler/cli/update.rb +21 -12
- data/lib/bundler/cli.rb +14 -11
- data/lib/bundler/definition.rb +61 -24
- data/lib/bundler/dependency.rb +4 -0
- data/lib/bundler/dsl.rb +77 -11
- data/lib/bundler/endpoint_specification.rb +51 -14
- data/lib/bundler/env.rb +7 -24
- data/lib/bundler/errors.rb +34 -5
- data/lib/bundler/fetcher/compact_index.rb +14 -5
- data/lib/bundler/fetcher/connection_pools.rb +150 -0
- data/lib/bundler/fetcher/downloader.rb +31 -16
- data/lib/bundler/fetcher.rb +8 -47
- data/lib/bundler/injector.rb +3 -3
- data/lib/bundler/inline.rb +44 -4
- data/lib/bundler/installer/parallel_installer.rb +25 -30
- data/lib/bundler/installer.rb +20 -6
- data/lib/bundler/lazy_specification.rb +44 -17
- data/lib/bundler/lockfile_generator.rb +24 -2
- data/lib/bundler/lockfile_parser.rb +43 -5
- data/lib/bundler/man/bundle-add.1 +7 -4
- data/lib/bundler/man/bundle-add.1.ronn +8 -4
- data/lib/bundler/man/bundle-binstubs.1 +1 -1
- data/lib/bundler/man/bundle-cache.1 +2 -2
- data/lib/bundler/man/bundle-cache.1.ronn +2 -2
- data/lib/bundler/man/bundle-check.1 +1 -1
- data/lib/bundler/man/bundle-clean.1 +1 -1
- data/lib/bundler/man/bundle-config.1 +38 -6
- data/lib/bundler/man/bundle-config.1.ronn +143 -10
- data/lib/bundler/man/bundle-console.1 +1 -1
- data/lib/bundler/man/bundle-doctor.1 +1 -1
- data/lib/bundler/man/bundle-env.1 +1 -1
- data/lib/bundler/man/bundle-exec.1 +1 -1
- data/lib/bundler/man/bundle-fund.1 +1 -1
- data/lib/bundler/man/bundle-gem.1 +1 -1
- data/lib/bundler/man/bundle-help.1 +1 -1
- data/lib/bundler/man/bundle-info.1 +1 -1
- data/lib/bundler/man/bundle-init.1 +1 -1
- data/lib/bundler/man/bundle-install.1 +2 -2
- data/lib/bundler/man/bundle-install.1.ronn +4 -4
- data/lib/bundler/man/bundle-issue.1 +1 -1
- data/lib/bundler/man/bundle-licenses.1 +1 -1
- data/lib/bundler/man/bundle-list.1 +1 -1
- data/lib/bundler/man/bundle-lock.1 +3 -3
- data/lib/bundler/man/bundle-lock.1.ronn +5 -5
- data/lib/bundler/man/bundle-open.1 +1 -1
- data/lib/bundler/man/bundle-outdated.1 +1 -1
- data/lib/bundler/man/bundle-platform.1 +1 -1
- data/lib/bundler/man/bundle-plugin.1 +1 -1
- data/lib/bundler/man/bundle-pristine.1 +1 -1
- data/lib/bundler/man/bundle-remove.1 +1 -1
- data/lib/bundler/man/bundle-show.1 +1 -1
- data/lib/bundler/man/bundle-update.1 +3 -3
- data/lib/bundler/man/bundle-update.1.ronn +3 -5
- data/lib/bundler/man/bundle-version.1 +1 -1
- data/lib/bundler/man/bundle.1 +1 -1
- data/lib/bundler/man/gemfile.5 +45 -1
- data/lib/bundler/man/gemfile.5.ronn +53 -0
- data/lib/bundler/match_metadata.rb +20 -0
- data/lib/bundler/match_platform.rb +25 -2
- data/lib/bundler/match_remote_metadata.rb +21 -6
- data/lib/bundler/materialization.rb +2 -1
- data/lib/bundler/override.rb +69 -0
- data/lib/bundler/plugin/dsl.rb +3 -5
- data/lib/bundler/plugin/events.rb +55 -13
- data/lib/bundler/plugin/index.rb +87 -11
- data/lib/bundler/plugin/installer/path.rb +1 -1
- data/lib/bundler/plugin/installer.rb +13 -5
- data/lib/bundler/plugin.rb +58 -30
- data/lib/bundler/remote_specification.rb +6 -3
- data/lib/bundler/resolver/base.rb +2 -1
- data/lib/bundler/resolver/incompatibility.rb +1 -1
- data/lib/bundler/resolver.rb +73 -23
- data/lib/bundler/ruby_version.rb +0 -2
- data/lib/bundler/rubygems_ext.rb +71 -1
- data/lib/bundler/rubygems_gem_installer.rb +41 -2
- data/lib/bundler/rubygems_integration.rb +7 -2
- data/lib/bundler/runtime.rb +69 -2
- data/lib/bundler/self_manager.rb +9 -15
- data/lib/bundler/settings.rb +373 -30
- data/lib/bundler/shared_helpers.rb +2 -1
- data/lib/bundler/source/git/git_proxy.rb +2 -10
- data/lib/bundler/source/git.rb +15 -6
- data/lib/bundler/source/path/installer.rb +1 -1
- data/lib/bundler/source/rubygems/remote.rb +10 -5
- data/lib/bundler/source/rubygems.rb +48 -12
- data/lib/bundler/spec_set.rb +16 -4
- data/lib/bundler/stub_specification.rb +2 -1
- data/lib/bundler/templates/newgem/Gemfile.tt +4 -4
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +3 -3
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +1 -1
- data/lib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt +1 -1
- data/lib/bundler/ui/shell.rb +0 -4
- data/lib/bundler/ui/silent.rb +0 -4
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +35 -2
- data/lib/bundler/vendor/thor/lib/thor/base.rb +2 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +14 -6
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +2 -0
- data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor.rb +34 -1
- data/lib/bundler/vendored_pub_grub.rb +5 -2
- data/lib/bundler/vendored_securerandom.rb +11 -8
- data/lib/bundler/vendored_uri.rb +14 -14
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler/worker.rb +3 -2
- data/lib/bundler.rb +1 -1
- data/lib/rubygems/compact_index_client/cache.rb +122 -0
- data/lib/rubygems/compact_index_client/cache_file.rb +147 -0
- data/lib/rubygems/compact_index_client/http_fetcher.rb +88 -0
- data/lib/rubygems/compact_index_client/parser.rb +90 -0
- data/lib/rubygems/compact_index_client/updater.rb +113 -0
- data/lib/rubygems/compact_index_client.rb +111 -0
- data/lib/rubygems/cooldown_settings.rb +57 -0
- data/lib/rubygems/credential_store/native/linux.rb +97 -0
- data/lib/rubygems/credential_store/native/macos.rb +88 -0
- data/lib/rubygems/credential_store/native/windows.rb +130 -0
- data/lib/rubygems/credential_store.rb +332 -0
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/assignment.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +7 -7
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/failure_writer.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/incompatibility.rb +4 -4
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/package.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/partial_solution.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/rubygems.rb +3 -3
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/solve_failure.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/static_package_source.rb +3 -3
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/strategy.rb +2 -2
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/term.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_constraint.rb +3 -3
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_range.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_solver.rb +2 -2
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_union.rb +1 -1
- data/lib/rubygems/vendor/pub_grub/lib/pub_grub.rb +57 -0
- data/lib/{bundler → rubygems}/vendor/securerandom/lib/securerandom.rb +10 -6
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/common.rb +119 -119
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/file.rb +13 -13
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ftp.rb +24 -24
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/generic.rb +132 -132
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/http.rb +18 -18
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/https.rb +4 -4
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ldap.rb +14 -14
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ldaps.rb +4 -4
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/mailto.rb +21 -21
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/rfc2396_parser.rb +39 -39
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/rfc3986_parser.rb +14 -14
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/version.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ws.rb +12 -12
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/wss.rb +4 -4
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri.rb +35 -31
- data/lib/rubygems/yaml_serializer.rb +880 -0
- metadata +77 -68
- data/CHANGELOG.md +0 -5784
- data/LICENSE.md +0 -22
- data/README.md +0 -58
- data/lib/bundler/compact_index_client/cache.rb +0 -107
- data/lib/bundler/compact_index_client/cache_file.rb +0 -148
- data/lib/bundler/compact_index_client/parser.rb +0 -87
- data/lib/bundler/compact_index_client/updater.rb +0 -105
- data/lib/bundler/compact_index_client.rb +0 -92
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +0 -227
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +0 -3
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +0 -56
- data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +0 -230
- data/lib/bundler/vendor/net-http-persistent/README.rdoc +0 -82
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +0 -41
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +0 -65
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +0 -80
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +0 -1153
- data/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +0 -31
- data/lib/bundler/vendored_persistent.rb +0 -11
- data/lib/bundler/yaml_serializer.rb +0 -98
- /data/lib/{bundler → rubygems}/vendor/pub_grub/LICENSE.txt +0 -0
- /data/lib/{bundler → rubygems}/vendor/securerandom/COPYING +0 -0
- /data/lib/{bundler → rubygems}/vendor/uri/COPYING +0 -0
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
##
|
|
2
|
-
# The TimedStack manages a pool of homogeneous connections (or any resource
|
|
3
|
-
# you wish to manage). Connections are created lazily up to a given maximum
|
|
4
|
-
# number.
|
|
5
|
-
#
|
|
6
|
-
# Examples:
|
|
7
|
-
#
|
|
8
|
-
# ts = TimedStack.new(1) { MyConnection.new }
|
|
9
|
-
#
|
|
10
|
-
# # fetch a connection
|
|
11
|
-
# conn = ts.pop
|
|
12
|
-
#
|
|
13
|
-
# # return a connection
|
|
14
|
-
# ts.push conn
|
|
15
|
-
#
|
|
16
|
-
# conn = ts.pop
|
|
17
|
-
# ts.pop timeout: 5
|
|
18
|
-
# #=> raises Bundler::ConnectionPool::TimeoutError after 5 seconds
|
|
19
|
-
class Bundler::ConnectionPool::TimedStack
|
|
20
|
-
attr_reader :max
|
|
21
|
-
|
|
22
|
-
##
|
|
23
|
-
# Creates a new pool with +size+ connections that are created from the given
|
|
24
|
-
# +block+.
|
|
25
|
-
def initialize(size = 0, &block)
|
|
26
|
-
@create_block = block
|
|
27
|
-
@created = 0
|
|
28
|
-
@que = []
|
|
29
|
-
@max = size
|
|
30
|
-
@mutex = Thread::Mutex.new
|
|
31
|
-
@resource = Thread::ConditionVariable.new
|
|
32
|
-
@shutdown_block = nil
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
##
|
|
36
|
-
# Returns +obj+ to the stack. +options+ is ignored in TimedStack but may be
|
|
37
|
-
# used by subclasses that extend TimedStack.
|
|
38
|
-
def push(obj, options = {})
|
|
39
|
-
@mutex.synchronize do
|
|
40
|
-
if @shutdown_block
|
|
41
|
-
@created -= 1 unless @created == 0
|
|
42
|
-
@shutdown_block.call(obj)
|
|
43
|
-
else
|
|
44
|
-
store_connection obj, options
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
@resource.broadcast
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
alias_method :<<, :push
|
|
51
|
-
|
|
52
|
-
##
|
|
53
|
-
# Retrieves a connection from the stack. If a connection is available it is
|
|
54
|
-
# immediately returned. If no connection is available within the given
|
|
55
|
-
# timeout a Bundler::ConnectionPool::TimeoutError is raised.
|
|
56
|
-
#
|
|
57
|
-
# +:timeout+ is the only checked entry in +options+ and is preferred over
|
|
58
|
-
# the +timeout+ argument (which will be removed in a future release). Other
|
|
59
|
-
# options may be used by subclasses that extend TimedStack.
|
|
60
|
-
def pop(timeout = 0.5, options = {})
|
|
61
|
-
options, timeout = timeout, 0.5 if Hash === timeout
|
|
62
|
-
timeout = options.fetch :timeout, timeout
|
|
63
|
-
|
|
64
|
-
deadline = current_time + timeout
|
|
65
|
-
@mutex.synchronize do
|
|
66
|
-
loop do
|
|
67
|
-
raise Bundler::ConnectionPool::PoolShuttingDownError if @shutdown_block
|
|
68
|
-
if (conn = try_fetch_connection(options))
|
|
69
|
-
return conn
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
connection = try_create(options)
|
|
73
|
-
return connection if connection
|
|
74
|
-
|
|
75
|
-
to_wait = deadline - current_time
|
|
76
|
-
raise Bundler::ConnectionPool::TimeoutError, "Waited #{timeout} sec, #{length}/#{@max} available" if to_wait <= 0
|
|
77
|
-
@resource.wait(@mutex, to_wait)
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
##
|
|
83
|
-
# Shuts down the TimedStack by passing each connection to +block+ and then
|
|
84
|
-
# removing it from the pool. Attempting to checkout a connection after
|
|
85
|
-
# shutdown will raise +Bundler::ConnectionPool::PoolShuttingDownError+ unless
|
|
86
|
-
# +:reload+ is +true+.
|
|
87
|
-
def shutdown(reload: false, &block)
|
|
88
|
-
raise ArgumentError, "shutdown must receive a block" unless block
|
|
89
|
-
|
|
90
|
-
@mutex.synchronize do
|
|
91
|
-
@shutdown_block = block
|
|
92
|
-
@resource.broadcast
|
|
93
|
-
|
|
94
|
-
shutdown_connections
|
|
95
|
-
@shutdown_block = nil if reload
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
##
|
|
100
|
-
# Reaps connections that were checked in more than +idle_seconds+ ago.
|
|
101
|
-
def reap(idle_seconds, &block)
|
|
102
|
-
raise ArgumentError, "reap must receive a block" unless block
|
|
103
|
-
raise ArgumentError, "idle_seconds must be a number" unless idle_seconds.is_a?(Numeric)
|
|
104
|
-
raise Bundler::ConnectionPool::PoolShuttingDownError if @shutdown_block
|
|
105
|
-
|
|
106
|
-
idle.times do
|
|
107
|
-
conn =
|
|
108
|
-
@mutex.synchronize do
|
|
109
|
-
raise Bundler::ConnectionPool::PoolShuttingDownError if @shutdown_block
|
|
110
|
-
|
|
111
|
-
reserve_idle_connection(idle_seconds)
|
|
112
|
-
end
|
|
113
|
-
break unless conn
|
|
114
|
-
|
|
115
|
-
block.call(conn)
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
##
|
|
120
|
-
# Returns +true+ if there are no available connections.
|
|
121
|
-
def empty?
|
|
122
|
-
(@created - @que.length) >= @max
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
##
|
|
126
|
-
# The number of connections available on the stack.
|
|
127
|
-
def length
|
|
128
|
-
@max - @created + @que.length
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
##
|
|
132
|
-
# The number of connections created and available on the stack.
|
|
133
|
-
def idle
|
|
134
|
-
@que.length
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
##
|
|
138
|
-
# Reduce the created count
|
|
139
|
-
def decrement_created
|
|
140
|
-
@created -= 1 unless @created == 0
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
private
|
|
144
|
-
|
|
145
|
-
def current_time
|
|
146
|
-
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
##
|
|
150
|
-
# This is an extension point for TimedStack and is called with a mutex.
|
|
151
|
-
#
|
|
152
|
-
# This method must returns a connection from the stack if one exists. Allows
|
|
153
|
-
# subclasses with expensive match/search algorithms to avoid double-handling
|
|
154
|
-
# their stack.
|
|
155
|
-
def try_fetch_connection(options = nil)
|
|
156
|
-
connection_stored?(options) && fetch_connection(options)
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
##
|
|
160
|
-
# This is an extension point for TimedStack and is called with a mutex.
|
|
161
|
-
#
|
|
162
|
-
# This method must returns true if a connection is available on the stack.
|
|
163
|
-
def connection_stored?(options = nil)
|
|
164
|
-
!@que.empty?
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
##
|
|
168
|
-
# This is an extension point for TimedStack and is called with a mutex.
|
|
169
|
-
#
|
|
170
|
-
# This method must return a connection from the stack.
|
|
171
|
-
def fetch_connection(options = nil)
|
|
172
|
-
@que.pop&.first
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
##
|
|
176
|
-
# This is an extension point for TimedStack and is called with a mutex.
|
|
177
|
-
#
|
|
178
|
-
# This method must shut down all connections on the stack.
|
|
179
|
-
def shutdown_connections(options = nil)
|
|
180
|
-
while (conn = try_fetch_connection(options))
|
|
181
|
-
@created -= 1 unless @created == 0
|
|
182
|
-
@shutdown_block.call(conn)
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
##
|
|
187
|
-
# This is an extension point for TimedStack and is called with a mutex.
|
|
188
|
-
#
|
|
189
|
-
# This method returns the oldest idle connection if it has been idle for more than idle_seconds.
|
|
190
|
-
# This requires that the stack is kept in order of checked in time (oldest first).
|
|
191
|
-
def reserve_idle_connection(idle_seconds)
|
|
192
|
-
return unless idle_connections?(idle_seconds)
|
|
193
|
-
|
|
194
|
-
@created -= 1 unless @created == 0
|
|
195
|
-
|
|
196
|
-
@que.shift.first
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
##
|
|
200
|
-
# This is an extension point for TimedStack and is called with a mutex.
|
|
201
|
-
#
|
|
202
|
-
# Returns true if the first connection in the stack has been idle for more than idle_seconds
|
|
203
|
-
def idle_connections?(idle_seconds)
|
|
204
|
-
connection_stored? && (current_time - @que.first.last > idle_seconds)
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
##
|
|
208
|
-
# This is an extension point for TimedStack and is called with a mutex.
|
|
209
|
-
#
|
|
210
|
-
# This method must return +obj+ to the stack.
|
|
211
|
-
def store_connection(obj, options = nil)
|
|
212
|
-
@que.push [obj, current_time]
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
##
|
|
216
|
-
# This is an extension point for TimedStack and is called with a mutex.
|
|
217
|
-
#
|
|
218
|
-
# This method must create a connection if and only if the total number of
|
|
219
|
-
# connections allowed has not been met.
|
|
220
|
-
def try_create(options = nil)
|
|
221
|
-
unless @created == @max
|
|
222
|
-
object = @create_block.call
|
|
223
|
-
@created += 1
|
|
224
|
-
object
|
|
225
|
-
end
|
|
226
|
-
end
|
|
227
|
-
end
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
class Bundler::ConnectionPool
|
|
2
|
-
class Wrapper < ::BasicObject
|
|
3
|
-
METHODS = [:with, :pool_shutdown, :wrapped_pool]
|
|
4
|
-
|
|
5
|
-
def initialize(options = {}, &block)
|
|
6
|
-
@pool = options.fetch(:pool) { ::Bundler::ConnectionPool.new(options, &block) }
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def wrapped_pool
|
|
10
|
-
@pool
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def with(&block)
|
|
14
|
-
@pool.with(&block)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def pool_shutdown(&block)
|
|
18
|
-
@pool.shutdown(&block)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def pool_size
|
|
22
|
-
@pool.size
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def pool_available
|
|
26
|
-
@pool.available
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def respond_to?(id, *args)
|
|
30
|
-
METHODS.include?(id) || with { |c| c.respond_to?(id, *args) }
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# rubocop:disable Style/MissingRespondToMissing
|
|
34
|
-
if ::RUBY_VERSION >= "3.0.0"
|
|
35
|
-
def method_missing(name, *args, **kwargs, &block)
|
|
36
|
-
with do |connection|
|
|
37
|
-
connection.send(name, *args, **kwargs, &block)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
elsif ::RUBY_VERSION >= "2.7.0"
|
|
41
|
-
ruby2_keywords def method_missing(name, *args, &block)
|
|
42
|
-
with do |connection|
|
|
43
|
-
connection.send(name, *args, &block)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
else
|
|
47
|
-
def method_missing(name, *args, &block)
|
|
48
|
-
with do |connection|
|
|
49
|
-
connection.send(name, *args, &block)
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
# rubocop:enable Style/MethodMissingSuper
|
|
54
|
-
# rubocop:enable Style/MissingRespondToMissing
|
|
55
|
-
end
|
|
56
|
-
end
|
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
require_relative "../../../vendored_timeout"
|
|
2
|
-
require_relative "connection_pool/version"
|
|
3
|
-
|
|
4
|
-
class Bundler::ConnectionPool
|
|
5
|
-
class Error < ::RuntimeError; end
|
|
6
|
-
|
|
7
|
-
class PoolShuttingDownError < ::Bundler::ConnectionPool::Error; end
|
|
8
|
-
|
|
9
|
-
class TimeoutError < ::Gem::Timeout::Error; end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
# Generic connection pool class for sharing a limited number of objects or network connections
|
|
13
|
-
# among many threads. Note: pool elements are lazily created.
|
|
14
|
-
#
|
|
15
|
-
# Example usage with block (faster):
|
|
16
|
-
#
|
|
17
|
-
# @pool = Bundler::ConnectionPool.new { Redis.new }
|
|
18
|
-
# @pool.with do |redis|
|
|
19
|
-
# redis.lpop('my-list') if redis.llen('my-list') > 0
|
|
20
|
-
# end
|
|
21
|
-
#
|
|
22
|
-
# Using optional timeout override (for that single invocation)
|
|
23
|
-
#
|
|
24
|
-
# @pool.with(timeout: 2.0) do |redis|
|
|
25
|
-
# redis.lpop('my-list') if redis.llen('my-list') > 0
|
|
26
|
-
# end
|
|
27
|
-
#
|
|
28
|
-
# Example usage replacing an existing connection (slower):
|
|
29
|
-
#
|
|
30
|
-
# $redis = Bundler::ConnectionPool.wrap { Redis.new }
|
|
31
|
-
#
|
|
32
|
-
# def do_work
|
|
33
|
-
# $redis.lpop('my-list') if $redis.llen('my-list') > 0
|
|
34
|
-
# end
|
|
35
|
-
#
|
|
36
|
-
# Accepts the following options:
|
|
37
|
-
# - :size - number of connections to pool, defaults to 5
|
|
38
|
-
# - :timeout - amount of time to wait for a connection if none currently available, defaults to 5 seconds
|
|
39
|
-
# - :auto_reload_after_fork - automatically drop all connections after fork, defaults to true
|
|
40
|
-
#
|
|
41
|
-
class Bundler::ConnectionPool
|
|
42
|
-
DEFAULTS = {size: 5, timeout: 5, auto_reload_after_fork: true}.freeze
|
|
43
|
-
|
|
44
|
-
def self.wrap(options, &block)
|
|
45
|
-
Wrapper.new(options, &block)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
if Process.respond_to?(:fork)
|
|
49
|
-
INSTANCES = ObjectSpace::WeakMap.new
|
|
50
|
-
private_constant :INSTANCES
|
|
51
|
-
|
|
52
|
-
def self.after_fork
|
|
53
|
-
INSTANCES.values.each do |pool|
|
|
54
|
-
next unless pool.auto_reload_after_fork
|
|
55
|
-
|
|
56
|
-
# We're on after fork, so we know all other threads are dead.
|
|
57
|
-
# All we need to do is to ensure the main thread doesn't have a
|
|
58
|
-
# checked out connection
|
|
59
|
-
pool.checkin(force: true)
|
|
60
|
-
pool.reload do |connection|
|
|
61
|
-
# Unfortunately we don't know what method to call to close the connection,
|
|
62
|
-
# so we try the most common one.
|
|
63
|
-
connection.close if connection.respond_to?(:close)
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
nil
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
if ::Process.respond_to?(:_fork) # MRI 3.1+
|
|
70
|
-
module ForkTracker
|
|
71
|
-
def _fork
|
|
72
|
-
pid = super
|
|
73
|
-
if pid == 0
|
|
74
|
-
Bundler::ConnectionPool.after_fork
|
|
75
|
-
end
|
|
76
|
-
pid
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
Process.singleton_class.prepend(ForkTracker)
|
|
80
|
-
end
|
|
81
|
-
else
|
|
82
|
-
INSTANCES = nil
|
|
83
|
-
private_constant :INSTANCES
|
|
84
|
-
|
|
85
|
-
def self.after_fork
|
|
86
|
-
# noop
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def initialize(options = {}, &block)
|
|
91
|
-
raise ArgumentError, "Connection pool requires a block" unless block
|
|
92
|
-
|
|
93
|
-
options = DEFAULTS.merge(options)
|
|
94
|
-
|
|
95
|
-
@size = Integer(options.fetch(:size))
|
|
96
|
-
@timeout = options.fetch(:timeout)
|
|
97
|
-
@auto_reload_after_fork = options.fetch(:auto_reload_after_fork)
|
|
98
|
-
|
|
99
|
-
@available = TimedStack.new(@size, &block)
|
|
100
|
-
@key = :"pool-#{@available.object_id}"
|
|
101
|
-
@key_count = :"pool-#{@available.object_id}-count"
|
|
102
|
-
@discard_key = :"pool-#{@available.object_id}-discard"
|
|
103
|
-
INSTANCES[self] = self if @auto_reload_after_fork && INSTANCES
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def with(options = {})
|
|
107
|
-
Thread.handle_interrupt(Exception => :never) do
|
|
108
|
-
conn = checkout(options)
|
|
109
|
-
begin
|
|
110
|
-
Thread.handle_interrupt(Exception => :immediate) do
|
|
111
|
-
yield conn
|
|
112
|
-
end
|
|
113
|
-
ensure
|
|
114
|
-
checkin
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
alias_method :then, :with
|
|
119
|
-
|
|
120
|
-
##
|
|
121
|
-
# Marks the current thread's checked-out connection for discard.
|
|
122
|
-
#
|
|
123
|
-
# When a connection is marked for discard, it will not be returned to the pool
|
|
124
|
-
# when checked in. Instead, the connection will be discarded.
|
|
125
|
-
# This is useful when a connection has become invalid or corrupted
|
|
126
|
-
# and should not be reused.
|
|
127
|
-
#
|
|
128
|
-
# Takes an optional block that will be called with the connection to be discarded.
|
|
129
|
-
# The block should perform any necessary clean-up on the connection.
|
|
130
|
-
#
|
|
131
|
-
# @yield [conn]
|
|
132
|
-
# @yieldparam conn [Object] The connection to be discarded.
|
|
133
|
-
# @yieldreturn [void]
|
|
134
|
-
#
|
|
135
|
-
#
|
|
136
|
-
# Note: This only affects the connection currently checked out by the calling thread.
|
|
137
|
-
# The connection will be discarded when +checkin+ is called.
|
|
138
|
-
#
|
|
139
|
-
# @return [void]
|
|
140
|
-
#
|
|
141
|
-
# @example
|
|
142
|
-
# pool.with do |conn|
|
|
143
|
-
# begin
|
|
144
|
-
# conn.execute("SELECT 1")
|
|
145
|
-
# rescue SomeConnectionError
|
|
146
|
-
# pool.discard_current_connection # Mark connection as bad
|
|
147
|
-
# raise
|
|
148
|
-
# end
|
|
149
|
-
# end
|
|
150
|
-
def discard_current_connection(&block)
|
|
151
|
-
::Thread.current[@discard_key] = block || proc { |conn| conn }
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def checkout(options = {})
|
|
155
|
-
if ::Thread.current[@key]
|
|
156
|
-
::Thread.current[@key_count] += 1
|
|
157
|
-
::Thread.current[@key]
|
|
158
|
-
else
|
|
159
|
-
::Thread.current[@key_count] = 1
|
|
160
|
-
::Thread.current[@key] = @available.pop(options[:timeout] || @timeout, options)
|
|
161
|
-
end
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
def checkin(force: false)
|
|
165
|
-
if ::Thread.current[@key]
|
|
166
|
-
if ::Thread.current[@key_count] == 1 || force
|
|
167
|
-
if ::Thread.current[@discard_key]
|
|
168
|
-
begin
|
|
169
|
-
@available.decrement_created
|
|
170
|
-
::Thread.current[@discard_key].call(::Thread.current[@key])
|
|
171
|
-
rescue
|
|
172
|
-
nil
|
|
173
|
-
ensure
|
|
174
|
-
::Thread.current[@discard_key] = nil
|
|
175
|
-
end
|
|
176
|
-
else
|
|
177
|
-
@available.push(::Thread.current[@key])
|
|
178
|
-
end
|
|
179
|
-
::Thread.current[@key] = nil
|
|
180
|
-
::Thread.current[@key_count] = nil
|
|
181
|
-
else
|
|
182
|
-
::Thread.current[@key_count] -= 1
|
|
183
|
-
end
|
|
184
|
-
elsif !force
|
|
185
|
-
raise Bundler::ConnectionPool::Error, "no connections are checked out"
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
nil
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
##
|
|
192
|
-
# Shuts down the Bundler::ConnectionPool by passing each connection to +block+ and
|
|
193
|
-
# then removing it from the pool. Attempting to checkout a connection after
|
|
194
|
-
# shutdown will raise +Bundler::ConnectionPool::PoolShuttingDownError+.
|
|
195
|
-
def shutdown(&block)
|
|
196
|
-
@available.shutdown(&block)
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
##
|
|
200
|
-
# Reloads the Bundler::ConnectionPool by passing each connection to +block+ and then
|
|
201
|
-
# removing it the pool. Subsequent checkouts will create new connections as
|
|
202
|
-
# needed.
|
|
203
|
-
def reload(&block)
|
|
204
|
-
@available.shutdown(reload: true, &block)
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
## Reaps idle connections that have been idle for over +idle_seconds+.
|
|
208
|
-
# +idle_seconds+ defaults to 60.
|
|
209
|
-
def reap(idle_seconds = 60, &block)
|
|
210
|
-
@available.reap(idle_seconds, &block)
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
# Size of this connection pool
|
|
214
|
-
attr_reader :size
|
|
215
|
-
# Automatically drop all connections after fork
|
|
216
|
-
attr_reader :auto_reload_after_fork
|
|
217
|
-
|
|
218
|
-
# Number of pool entries available for checkout at this instant.
|
|
219
|
-
def available
|
|
220
|
-
@available.length
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
# Number of pool entries created and idle in the pool.
|
|
224
|
-
def idle
|
|
225
|
-
@available.idle
|
|
226
|
-
end
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
require_relative "connection_pool/timed_stack"
|
|
230
|
-
require_relative "connection_pool/wrapper"
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
= net-http-persistent
|
|
2
|
-
|
|
3
|
-
home :: https://github.com/drbrain/net-http-persistent
|
|
4
|
-
rdoc :: https://rubydoc.info/gems/net-http-persistent
|
|
5
|
-
|
|
6
|
-
== DESCRIPTION:
|
|
7
|
-
|
|
8
|
-
Manages persistent connections using Net::HTTP including a thread pool for
|
|
9
|
-
connecting to multiple hosts.
|
|
10
|
-
|
|
11
|
-
Using persistent HTTP connections can dramatically increase the speed of HTTP.
|
|
12
|
-
Creating a new HTTP connection for every request involves an extra TCP
|
|
13
|
-
round-trip and causes TCP congestion avoidance negotiation to start over.
|
|
14
|
-
|
|
15
|
-
Net::HTTP supports persistent connections with some API methods but does not
|
|
16
|
-
make setting up a single persistent connection or managing multiple
|
|
17
|
-
connections easy. Net::HTTP::Persistent wraps Net::HTTP and allows you to
|
|
18
|
-
focus on how to make HTTP requests.
|
|
19
|
-
|
|
20
|
-
== FEATURES/PROBLEMS:
|
|
21
|
-
|
|
22
|
-
* Supports TLS with secure defaults
|
|
23
|
-
* Thread-safe
|
|
24
|
-
* Pure ruby
|
|
25
|
-
|
|
26
|
-
== SYNOPSIS
|
|
27
|
-
|
|
28
|
-
The following example will make two requests to the same server. The
|
|
29
|
-
connection is kept alive between requests:
|
|
30
|
-
|
|
31
|
-
require 'net/http/persistent'
|
|
32
|
-
|
|
33
|
-
uri = URI 'http://example.com/awesome/web/service'
|
|
34
|
-
|
|
35
|
-
http = Net::HTTP::Persistent.new name: 'my_app_name'
|
|
36
|
-
|
|
37
|
-
# perform a GET
|
|
38
|
-
response = http.request uri
|
|
39
|
-
|
|
40
|
-
# create a POST
|
|
41
|
-
post_uri = uri + 'create'
|
|
42
|
-
post = Net::HTTP::Post.new post_uri.path
|
|
43
|
-
post.set_form_data 'some' => 'cool data'
|
|
44
|
-
|
|
45
|
-
# perform the POST, the URI is always required
|
|
46
|
-
response = http.request post_uri, post
|
|
47
|
-
|
|
48
|
-
# if you are done making http requests, or won't make requests for several
|
|
49
|
-
# minutes
|
|
50
|
-
http.shutdown
|
|
51
|
-
|
|
52
|
-
Please see the documentation on Net::HTTP::Persistent for more information,
|
|
53
|
-
including SSL connection verification, header handling and tunable options.
|
|
54
|
-
|
|
55
|
-
== INSTALL:
|
|
56
|
-
|
|
57
|
-
gem install net-http-persistent
|
|
58
|
-
|
|
59
|
-
== LICENSE:
|
|
60
|
-
|
|
61
|
-
(The MIT License)
|
|
62
|
-
|
|
63
|
-
Copyright (c) Eric Hodel, Aaron Patterson
|
|
64
|
-
|
|
65
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
|
66
|
-
a copy of this software and associated documentation files (the
|
|
67
|
-
'Software'), to deal in the Software without restriction, including
|
|
68
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
|
69
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
|
70
|
-
permit persons to whom the Software is furnished to do so, subject to
|
|
71
|
-
the following conditions:
|
|
72
|
-
|
|
73
|
-
The above copyright notice and this permission notice shall be
|
|
74
|
-
included in all copies or substantial portions of the Software.
|
|
75
|
-
|
|
76
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
77
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
78
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
79
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
80
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
81
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
82
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
##
|
|
2
|
-
# A Gem::Net::HTTP connection wrapper that holds extra information for managing the
|
|
3
|
-
# connection's lifetime.
|
|
4
|
-
|
|
5
|
-
class Gem::Net::HTTP::Persistent::Connection # :nodoc:
|
|
6
|
-
|
|
7
|
-
attr_accessor :http
|
|
8
|
-
|
|
9
|
-
attr_accessor :last_use
|
|
10
|
-
|
|
11
|
-
attr_accessor :requests
|
|
12
|
-
|
|
13
|
-
attr_accessor :ssl_generation
|
|
14
|
-
|
|
15
|
-
def initialize http_class, http_args, ssl_generation
|
|
16
|
-
@http = http_class.new(*http_args)
|
|
17
|
-
@ssl_generation = ssl_generation
|
|
18
|
-
|
|
19
|
-
reset
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def finish
|
|
23
|
-
@http.finish
|
|
24
|
-
rescue IOError
|
|
25
|
-
ensure
|
|
26
|
-
reset
|
|
27
|
-
end
|
|
28
|
-
alias_method :close, :finish
|
|
29
|
-
|
|
30
|
-
def reset
|
|
31
|
-
@last_use = Gem::Net::HTTP::Persistent::EPOCH
|
|
32
|
-
@requests = 0
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def ressl ssl_generation
|
|
36
|
-
@ssl_generation = ssl_generation
|
|
37
|
-
|
|
38
|
-
finish
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
end
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
class Gem::Net::HTTP::Persistent::Pool < Bundler::ConnectionPool # :nodoc:
|
|
2
|
-
|
|
3
|
-
attr_reader :available # :nodoc:
|
|
4
|
-
attr_reader :key # :nodoc:
|
|
5
|
-
|
|
6
|
-
def initialize(options = {}, &block)
|
|
7
|
-
super
|
|
8
|
-
|
|
9
|
-
@available = Gem::Net::HTTP::Persistent::TimedStackMulti.new(@size, &block)
|
|
10
|
-
@key = "current-#{@available.object_id}"
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def checkin net_http_args
|
|
14
|
-
if net_http_args.is_a?(Hash) && net_http_args.size == 1 && net_http_args[:force]
|
|
15
|
-
# Bundler::ConnectionPool 2.4+ calls `checkin(force: true)` after fork.
|
|
16
|
-
# When this happens, we should remove all connections from Thread.current
|
|
17
|
-
if stacks = Thread.current[@key]
|
|
18
|
-
stacks.each do |http_args, connections|
|
|
19
|
-
connections.each do |conn|
|
|
20
|
-
@available.push conn, connection_args: http_args
|
|
21
|
-
end
|
|
22
|
-
connections.clear
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
else
|
|
26
|
-
stack = Thread.current[@key][net_http_args] ||= []
|
|
27
|
-
|
|
28
|
-
raise Bundler::ConnectionPool::Error, 'no connections are checked out' if
|
|
29
|
-
stack.empty?
|
|
30
|
-
|
|
31
|
-
conn = stack.pop
|
|
32
|
-
|
|
33
|
-
if stack.empty?
|
|
34
|
-
@available.push conn, connection_args: net_http_args
|
|
35
|
-
|
|
36
|
-
Thread.current[@key].delete(net_http_args)
|
|
37
|
-
Thread.current[@key] = nil if Thread.current[@key].empty?
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
nil
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def checkout net_http_args
|
|
44
|
-
stacks = Thread.current[@key] ||= {}
|
|
45
|
-
stack = stacks[net_http_args] ||= []
|
|
46
|
-
|
|
47
|
-
if stack.empty? then
|
|
48
|
-
conn = @available.pop connection_args: net_http_args
|
|
49
|
-
else
|
|
50
|
-
conn = stack.last
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
stack.push conn
|
|
54
|
-
|
|
55
|
-
conn
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def shutdown
|
|
59
|
-
Thread.current[@key] = nil
|
|
60
|
-
super
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
require_relative 'timed_stack_multi'
|
|
65
|
-
|