concurrent-ruby 1.3.3 → 1.3.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ca6244c1124d507f5422c42cc9376e46cb2a46f7ad07363731ee0957c410e98
4
- data.tar.gz: 4c03cbe71e12804bf8d9b0c707895313206a9932be3e182f1674faa70568ca1f
3
+ metadata.gz: 01c9677c137013ec86d98778a4aa6a9e69bca9b0ae29e923a37254c9cdc515fe
4
+ data.tar.gz: 3be169b6d0a11914f85e4a0e1221cd5c122bd59035abe9718892e1a3b4bc690b
5
5
  SHA512:
6
- metadata.gz: ceaab8640927f5f0bf5ecde7727705248d5dd5d0a5fe9b4baa8b8d259a2cf0ef9a5e8d636cfacd47588d358ea8c51cd1650f0939be6e3188647553e7158d536f
7
- data.tar.gz: 216aed72a0d32b40a7e34303751d9c544594b4a51e38e9fd449f3922fcc30fd9a7549d22d7e3d1552b307806ede6c638acffdaded8cd016980a0ae0683b5495e
6
+ metadata.gz: 89544dfc5575906cac0f5c57ce5348b944a70a6f77154fb70d0f185b9cc79344a5bb5147a7cf22808e071b4213c80c94e3036b98a2f4102018daf8ba16492db8
7
+ data.tar.gz: f084a5a9aa8c6e2ad305fe360f1e8e3b264ad0b45f7add6c04561ff4945cbf0b7c30b2c0d6801be46bc61b3f22f60975e8397973a321268bbf302f4bcb65ab24
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## Current
2
2
 
3
+ ## Release v1.3.4 (10 August 2024)
4
+
5
+ * (#1060) Fix bug with return value of `Concurrent.available_processor_count` when `cpu.cfs_quota_us` is -1.
6
+ * (#1058) Add `Concurrent.cpu_shares` that is cgroups aware.
7
+
3
8
  ## Release v1.3.3 (9 June 2024)
4
9
 
5
10
  * (#1053) Improve the speed of `Concurrent.physical_processor_count` on Windows.
data/Gemfile CHANGED
@@ -1,14 +1,14 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- require File.join(File.dirname(__FILE__), 'lib/concurrent-ruby/concurrent/version')
4
- require File.join(File.dirname(__FILE__ ), 'lib/concurrent-ruby-edge/concurrent/edge/version')
3
+ version = File.read("#{__dir__}/lib/concurrent-ruby/concurrent/version.rb")[/'(.+)'/, 1] or raise
4
+ edge_version = File.read("#{__dir__}/lib/concurrent-ruby-edge/concurrent/edge/version.rb")[/'(.+)'/, 1] or raise
5
5
 
6
6
  no_path = ENV['NO_PATH']
7
7
  options = no_path ? {} : { path: '.' }
8
8
 
9
- gem 'concurrent-ruby', Concurrent::VERSION, options
10
- gem 'concurrent-ruby-edge', Concurrent::EDGE_VERSION, options
11
- gem 'concurrent-ruby-ext', Concurrent::VERSION, options.merge(platform: :mri)
9
+ gem 'concurrent-ruby', version, options
10
+ gem 'concurrent-ruby-edge', edge_version, options
11
+ gem 'concurrent-ruby-ext', version, options.merge(platform: :mri)
12
12
 
13
13
  group :development do
14
14
  gem 'rake', '~> 13.0'
data/Rakefile CHANGED
@@ -1,6 +1,5 @@
1
- require_relative 'lib/concurrent-ruby/concurrent/version'
2
- require_relative 'lib/concurrent-ruby-edge/concurrent/edge/version'
3
- require_relative 'lib/concurrent-ruby/concurrent/utility/engine'
1
+ version = File.read("#{__dir__}/lib/concurrent-ruby/concurrent/version.rb")[/'(.+)'/, 1] or raise
2
+ edge_version = File.read("#{__dir__}/lib/concurrent-ruby-edge/concurrent/edge/version.rb")[/'(.+)'/, 1] or raise
4
3
 
5
4
  core_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby.gemspec')
6
5
  ext_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-ext.gemspec')
@@ -8,14 +7,14 @@ edge_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-edge.
8
7
 
9
8
  require 'rake/javaextensiontask'
10
9
 
11
- ENV['JRUBY_HOME'] = ENV['CONCURRENT_JRUBY_HOME'] if ENV['CONCURRENT_JRUBY_HOME'] && !Concurrent.on_jruby?
10
+ ENV['JRUBY_HOME'] = ENV['CONCURRENT_JRUBY_HOME'] if ENV['CONCURRENT_JRUBY_HOME'] && RUBY_ENGINE != 'jruby'
12
11
 
13
12
  Rake::JavaExtensionTask.new('concurrent_ruby', core_gemspec) do |ext|
14
13
  ext.ext_dir = 'ext/concurrent-ruby'
15
14
  ext.lib_dir = 'lib/concurrent-ruby/concurrent'
16
15
  end
17
16
 
18
- unless Concurrent.on_jruby? || Concurrent.on_truffleruby?
17
+ if RUBY_ENGINE == 'ruby'
19
18
  require 'rake/extensiontask'
20
19
 
21
20
  Rake::ExtensionTask.new('concurrent_ruby_ext', ext_gemspec) do |ext|
@@ -68,7 +67,7 @@ require 'rubygems'
68
67
  require 'rubygems/package_task'
69
68
 
70
69
  Gem::PackageTask.new(core_gemspec) {} if core_gemspec
71
- Gem::PackageTask.new(ext_gemspec) {} if ext_gemspec && !Concurrent.on_jruby?
70
+ Gem::PackageTask.new(ext_gemspec) {} if ext_gemspec && RUBY_ENGINE != 'jruby'
72
71
  Gem::PackageTask.new(edge_gemspec) {} if edge_gemspec
73
72
 
74
73
  CLEAN.include(
@@ -96,9 +95,9 @@ begin
96
95
  task :installed do
97
96
  Bundler.with_original_env do
98
97
  Dir.chdir(__dir__) do
99
- sh "gem install pkg/concurrent-ruby-#{Concurrent::VERSION}.gem"
100
- sh "gem install pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem" if Concurrent.on_cruby?
101
- sh "gem install pkg/concurrent-ruby-edge-#{Concurrent::EDGE_VERSION}.gem"
98
+ sh "gem install pkg/concurrent-ruby-#{version}.gem"
99
+ sh "gem install pkg/concurrent-ruby-ext-#{version}.gem" if RUBY_ENGINE == 'ruby'
100
+ sh "gem install pkg/concurrent-ruby-edge-#{edge_version}.gem"
102
101
  ENV['NO_PATH'] = 'true'
103
102
  sh 'bundle update'
104
103
  sh 'bundle exec rake spec:ci'
@@ -128,7 +127,7 @@ rescue LoadError => e
128
127
  puts 'RSpec is not installed, skipping test task definitions: ' + e.message
129
128
  end
130
129
 
131
- current_yard_version_name = Concurrent::VERSION
130
+ current_yard_version_name = version
132
131
 
133
132
  begin
134
133
  require 'yard'
@@ -232,6 +231,8 @@ namespace :release do
232
231
  # Depends on environment of @pitr-ch
233
232
 
234
233
  task :checks do
234
+ raise '$CONCURRENT_JRUBY_HOME must be set' unless ENV['CONCURRENT_JRUBY_HOME']
235
+
235
236
  Dir.chdir(__dir__) do
236
237
  sh 'test -z "$(git status --porcelain)"' do |ok, res|
237
238
  unless ok
@@ -262,6 +263,8 @@ namespace :release do
262
263
 
263
264
  desc '* test actual installed gems instead of cloned repository on MRI and JRuby'
264
265
  task :test do
266
+ raise '$CONCURRENT_JRUBY_HOME must be set' unless ENV['CONCURRENT_JRUBY_HOME']
267
+
265
268
  Dir.chdir(__dir__) do
266
269
  puts "Testing with the installed gem"
267
270
 
@@ -310,21 +313,21 @@ namespace :release do
310
313
  desc '** tag HEAD with current version and push to github'
311
314
  task :tag => :ask do
312
315
  Dir.chdir(__dir__) do
313
- sh "git tag v#{Concurrent::VERSION}" if publish_base
314
- sh "git push origin v#{Concurrent::VERSION}" if publish_base
315
- sh "git tag edge-v#{Concurrent::EDGE_VERSION}" if publish_edge
316
- sh "git push origin edge-v#{Concurrent::EDGE_VERSION}" if publish_edge
316
+ sh "git tag v#{version}" if publish_base
317
+ sh "git push origin v#{version}" if publish_base
318
+ sh "git tag edge-v#{edge_version}" if publish_edge
319
+ sh "git push origin edge-v#{edge_version}" if publish_edge
317
320
  end
318
321
  end
319
322
 
320
323
  desc '** push all *.gem files to rubygems'
321
324
  task :rubygems => :ask do
322
325
  Dir.chdir(__dir__) do
323
- sh "gem push pkg/concurrent-ruby-#{Concurrent::VERSION}.gem" if publish_base
324
- sh "gem push pkg/concurrent-ruby-edge-#{Concurrent::EDGE_VERSION}.gem" if publish_edge
325
- sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem" if publish_base
326
- sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x64-mingw32.gem" if publish_base
327
- sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x86-mingw32.gem" if publish_base
326
+ sh "gem push pkg/concurrent-ruby-#{version}.gem" if publish_base
327
+ sh "gem push pkg/concurrent-ruby-edge-#{edge_version}.gem" if publish_edge
328
+ sh "gem push pkg/concurrent-ruby-ext-#{version}.gem" if publish_base
329
+ sh "gem push pkg/concurrent-ruby-ext-#{version}-x64-mingw32.gem" if publish_base
330
+ sh "gem push pkg/concurrent-ruby-ext-#{version}-x86-mingw32.gem" if publish_base
328
331
  end
329
332
  end
330
333
 
@@ -12,6 +12,7 @@ module Concurrent
12
12
  @processor_count = Delay.new { compute_processor_count }
13
13
  @physical_processor_count = Delay.new { compute_physical_processor_count }
14
14
  @cpu_quota = Delay.new { compute_cpu_quota }
15
+ @cpu_shares = Delay.new { compute_cpu_shares }
15
16
  end
16
17
 
17
18
  def processor_count
@@ -41,6 +42,10 @@ module Concurrent
41
42
  @cpu_quota.value
42
43
  end
43
44
 
45
+ def cpu_shares
46
+ @cpu_shares.value
47
+ end
48
+
44
49
  private
45
50
 
46
51
  def compute_processor_count
@@ -78,7 +83,7 @@ module Concurrent
78
83
  # Bail out if both commands returned something unexpected
79
84
  processor_count
80
85
  else
81
- # powershell: "\nNumberOfCores\n-------------\n 4\n\n\n"
86
+ # powershell: "\nNumberOfCores\n-------------\n 4\n\n\n"
82
87
  # wmic: "NumberOfCores \n\n4 \n\n\n\n"
83
88
  result.scan(/\d+/).map(&:to_i).reduce(:+)
84
89
  end
@@ -107,12 +112,28 @@ module Concurrent
107
112
  elsif File.exist?("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us")
108
113
  # cgroups v1: https://kernel.googlesource.com/pub/scm/linux/kernel/git/glommer/memcg/+/cpu_stat/Documentation/cgroups/cpu.txt
109
114
  max = File.read("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us").to_i
110
- return nil if max == 0
115
+ # If the cpu.cfs_quota_us is -1, cgroup does not adhere to any CPU time restrictions
116
+ # https://docs.kernel.org/scheduler/sched-bwc.html#management
117
+ return nil if max <= 0
111
118
  period = File.read("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us").to_f
112
119
  max / period
113
120
  end
114
121
  end
115
122
  end
123
+
124
+ def compute_cpu_shares
125
+ if RbConfig::CONFIG["target_os"].include?("linux")
126
+ if File.exist?("/sys/fs/cgroup/cpu.weight")
127
+ # cgroups v2: https://docs.kernel.org/admin-guide/cgroup-v2.html#cpu-interface-files
128
+ # Ref: https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2254-cgroup-v2#phase-1-convert-from-cgroups-v1-settings-to-v2
129
+ weight = File.read("/sys/fs/cgroup/cpu.weight").to_f
130
+ ((((weight - 1) * 262142) / 9999) + 2) / 1024
131
+ elsif File.exist?("/sys/fs/cgroup/cpu/cpu.shares")
132
+ # cgroups v1: https://kernel.googlesource.com/pub/scm/linux/kernel/git/glommer/memcg/+/cpu_stat/Documentation/cgroups/cpu.txt
133
+ File.read("/sys/fs/cgroup/cpu/cpu.shares").to_f / 1024
134
+ end
135
+ end
136
+ end
116
137
  end
117
138
  end
118
139
 
@@ -128,8 +149,8 @@ module Concurrent
128
149
  # `java.lang.Runtime.getRuntime.availableProcessors` will be used. According
129
150
  # to the Java documentation this "value may change during a particular
130
151
  # invocation of the virtual machine... [applications] should therefore
131
- # occasionally poll this property." Subsequently the result will NOT be
132
- # memoized under JRuby.
152
+ # occasionally poll this property." We still memoize this value once under
153
+ # JRuby.
133
154
  #
134
155
  # Otherwise Ruby's Etc.nprocessors will be used.
135
156
  #
@@ -162,13 +183,14 @@ module Concurrent
162
183
  end
163
184
 
164
185
  # Number of processors cores available for process scheduling.
165
- # Returns `nil` if there is no #cpu_quota, or a `Float` if the
166
- # process is inside a cgroup with a dedicated CPU quota (typically Docker).
186
+ # This method takes in account the CPU quota if the process is inside a cgroup with a
187
+ # dedicated CPU quota (typically Docker).
188
+ # Otherwise it returns the same value as #processor_count but as a Float.
167
189
  #
168
190
  # For performance reasons the calculated value will be memoized on the first
169
191
  # call.
170
192
  #
171
- # @return [nil, Float] number of available processors
193
+ # @return [Float] number of available processors
172
194
  def self.available_processor_count
173
195
  processor_counter.available_processor_count
174
196
  end
@@ -187,4 +209,12 @@ module Concurrent
187
209
  def self.cpu_quota
188
210
  processor_counter.cpu_quota
189
211
  end
212
+
213
+ # The CPU shares requested by the process. For performance reasons the calculated
214
+ # value will be memoized on the first call.
215
+ #
216
+ # @return [Float, nil] CPU shares requested by the process, or nil if not set
217
+ def self.cpu_shares
218
+ processor_counter.cpu_shares
219
+ end
190
220
  end
@@ -1,3 +1,3 @@
1
1
  module Concurrent
2
- VERSION = '1.3.3'
2
+ VERSION = '1.3.4'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: concurrent-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.3
4
+ version: 1.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jerry D'Antonio
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-06-09 00:00:00.000000000 Z
13
+ date: 2024-08-10 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: |
16
16
  Modern concurrency tools including agents, futures, promises, thread pools, actors, supervisors, and more.