concurrent-ruby 1.2.3 → 1.3.3

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: 1c6483d36c3c75859c9b38b6ba2ba13577a0bb89b3b725a032d43f3543797099
4
- data.tar.gz: e94ac3e1ba23db29a7bf025736e34a4027ba7a137ae08b493c78ce3756803792
3
+ metadata.gz: 1ca6244c1124d507f5422c42cc9376e46cb2a46f7ad07363731ee0957c410e98
4
+ data.tar.gz: 4c03cbe71e12804bf8d9b0c707895313206a9932be3e182f1674faa70568ca1f
5
5
  SHA512:
6
- metadata.gz: dc0353e60638a409bf891d663626bd2c1c5f05206c08036326d63e239bfe0ea7e1e3480982c75fe44f9d416a7f76a66a2a2aeef78fc60084ed7ff94c7d3181d9
7
- data.tar.gz: 24bdd3a040528c05061ec15b4057184be96fa933f69f3321755e8583ba8e6175beec48c36f1671cc3dad7e413588c9601c7f0e5b503b3de947dff63c2ba76b1e
6
+ metadata.gz: ceaab8640927f5f0bf5ecde7727705248d5dd5d0a5fe9b4baa8b8d259a2cf0ef9a5e8d636cfacd47588d358ea8c51cd1650f0939be6e3188647553e7158d536f
7
+ data.tar.gz: 216aed72a0d32b40a7e34303751d9c544594b4a51e38e9fd449f3922fcc30fd9a7549d22d7e3d1552b307806ede6c638acffdaded8cd016980a0ae0683b5495e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  ## Current
2
2
 
3
+ ## Release v1.3.3 (9 June 2024)
4
+
5
+ * (#1053) Improve the speed of `Concurrent.physical_processor_count` on Windows.
6
+
7
+ ## Release v1.3.2, edge v0.7.1 (7 June 2024)
8
+
9
+ concurrent-ruby:
10
+
11
+ * (#1051) Remove dependency on `win32ole`.
12
+
13
+ concurrent-ruby-edge:
14
+
15
+ * (#1052) Fix dependency on `concurrent-ruby` to allow the latest release.
16
+
17
+ ## Release v1.3.1 (29 May 2024)
18
+
19
+ * Release 1.3.0 was broken when pushed to RubyGems. 1.3.1 is a packaging fix.
20
+
21
+ ## Release v1.3.0 (28 May 2024)
22
+
23
+ * (#1042) Align Java Executor Service behavior for `shuttingdown?`, `shutdown?`
24
+ * (#1038) Add `Concurrent.available_processor_count` that is cgroups aware.
25
+
3
26
  ## Release v1.2.3 (16 Jan 2024)
4
27
 
5
28
  * See [the GitHub release](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.2.3) for details.
data/Rakefile CHANGED
@@ -28,6 +28,10 @@ unless Concurrent.on_jruby? || Concurrent.on_truffleruby?
28
28
  end
29
29
  end
30
30
 
31
+ def which?(executable)
32
+ !`which #{executable} 2>/dev/null`.empty?
33
+ end
34
+
31
35
  require 'rake_compiler_dock'
32
36
  namespace :repackage do
33
37
  desc '* with Windows fat distributions'
@@ -42,12 +46,19 @@ namespace :repackage do
42
46
  Rake::Task['lib/concurrent-ruby/concurrent/concurrent_ruby.jar'].invoke
43
47
 
44
48
  # build all gem files
49
+ rack_compiler_dock_kwargs = {}
50
+ if which?('podman') and (!which?('docker') || `docker --version`.include?('podman'))
51
+ # podman and only podman available, so RakeCompilerDock will use podman, otherwise it uses docker
52
+ rack_compiler_dock_kwargs = {
53
+ options: ['--privileged'], # otherwise the directory in the image is empty
54
+ runas: false
55
+ }
56
+ end
45
57
  %w[x86-mingw32 x64-mingw32].each do |plat|
46
58
  RakeCompilerDock.sh(
47
59
  "bundle install --local && bundle exec rake native:#{plat} gem --trace",
48
60
  platform: plat,
49
- options: ['--privileged'], # otherwise the directory in the image is empty
50
- runas: false)
61
+ **rack_compiler_dock_kwargs)
51
62
  end
52
63
  end
53
64
  end
@@ -256,10 +267,12 @@ namespace :release do
256
267
 
257
268
  Bundler.with_original_env do
258
269
  sh 'ruby -v'
270
+ sh 'bundle install'
259
271
  sh 'bundle exec rake spec:installed'
260
272
 
261
- env = { "PATH" => "#{ENV['CONCURRENT_JRUBY_HOME']}/bin:#{ENV['PATH']}" }
273
+ env = { "PATH" => "#{ENV.fetch('CONCURRENT_JRUBY_HOME')}/bin:#{ENV['PATH']}" }
262
274
  sh env, 'ruby -v'
275
+ sh env, 'bundle install'
263
276
  sh env, 'bundle exec rake spec:installed'
264
277
  end
265
278
 
@@ -271,8 +284,8 @@ namespace :release do
271
284
  task :publish => ['publish:ask', 'publish:tag', 'publish:rubygems', 'publish:post_steps']
272
285
 
273
286
  namespace :publish do
274
- publish_base = true
275
- publish_edge = false
287
+ publish_base = nil
288
+ publish_edge = nil
276
289
 
277
290
  task :ask do
278
291
  begin
@@ -280,8 +293,15 @@ namespace :release do
280
293
  input = STDIN.gets.strip.downcase
281
294
  end until %w(y n).include?(input)
282
295
  exit 1 if input == 'n'
296
+
297
+ begin
298
+ STDOUT.puts 'Do you want to publish `concurrent-ruby`? (y/n)'
299
+ input = STDIN.gets.strip.downcase
300
+ end until %w(y n).include?(input)
301
+ publish_base = input == 'y'
302
+
283
303
  begin
284
- STDOUT.puts 'It will publish `concurrent-ruby`. Do you want to publish `concurrent-ruby-edge`? (y/n)'
304
+ STDOUT.puts 'Do you want to publish `concurrent-ruby-edge`? (y/n)'
285
305
  input = STDIN.gets.strip.downcase
286
306
  end until %w(y n).include?(input)
287
307
  publish_edge = input == 'y'
@@ -57,15 +57,11 @@ if Concurrent.on_jruby?
57
57
  end
58
58
 
59
59
  def ns_shuttingdown?
60
- if @executor.respond_to? :isTerminating
61
- @executor.isTerminating
62
- else
63
- false
64
- end
60
+ @executor.isShutdown && !@executor.isTerminated
65
61
  end
66
62
 
67
63
  def ns_shutdown?
68
- @executor.isShutdown || @executor.isTerminated
64
+ @executor.isTerminated
69
65
  end
70
66
 
71
67
  class Job
@@ -11,6 +11,7 @@ module Concurrent
11
11
  def initialize
12
12
  @processor_count = Delay.new { compute_processor_count }
13
13
  @physical_processor_count = Delay.new { compute_physical_processor_count }
14
+ @cpu_quota = Delay.new { compute_cpu_quota }
14
15
  end
15
16
 
16
17
  def processor_count
@@ -21,6 +22,25 @@ module Concurrent
21
22
  @physical_processor_count.value
22
23
  end
23
24
 
25
+ def available_processor_count
26
+ cpu_count = processor_count.to_f
27
+ quota = cpu_quota
28
+
29
+ return cpu_count if quota.nil?
30
+
31
+ # cgroup cpus quotas have no limits, so they can be set to higher than the
32
+ # real count of cores.
33
+ if quota > cpu_count
34
+ cpu_count
35
+ else
36
+ quota
37
+ end
38
+ end
39
+
40
+ def cpu_quota
41
+ @cpu_quota.value
42
+ end
43
+
24
44
  private
25
45
 
26
46
  def compute_processor_count
@@ -48,10 +68,20 @@ module Concurrent
48
68
  end
49
69
  cores.count
50
70
  when /mswin|mingw/
51
- require 'win32ole'
52
- result_set = WIN32OLE.connect("winmgmts://").ExecQuery(
53
- "select NumberOfCores from Win32_Processor")
54
- result_set.to_enum.collect(&:NumberOfCores).reduce(:+)
71
+ # Get-CimInstance introduced in PowerShell 3 or earlier: https://learn.microsoft.com/en-us/previous-versions/powershell/module/cimcmdlets/get-ciminstance?view=powershell-3.0
72
+ result = run('powershell -command "Get-CimInstance -ClassName Win32_Processor -Property NumberOfCores | Select-Object -Property NumberOfCores"')
73
+ if !result || $?.exitstatus != 0
74
+ # fallback to deprecated wmic for older systems
75
+ result = run("wmic cpu get NumberOfCores")
76
+ end
77
+ if !result || $?.exitstatus != 0
78
+ # Bail out if both commands returned something unexpected
79
+ processor_count
80
+ else
81
+ # powershell: "\nNumberOfCores\n-------------\n 4\n\n\n"
82
+ # wmic: "NumberOfCores \n\n4 \n\n\n\n"
83
+ result.scan(/\d+/).map(&:to_i).reduce(:+)
84
+ end
55
85
  else
56
86
  processor_count
57
87
  end
@@ -60,6 +90,29 @@ module Concurrent
60
90
  rescue
61
91
  return 1
62
92
  end
93
+
94
+ def run(command)
95
+ IO.popen(command, &:read)
96
+ rescue Errno::ENOENT
97
+ end
98
+
99
+ def compute_cpu_quota
100
+ if RbConfig::CONFIG["target_os"].include?("linux")
101
+ if File.exist?("/sys/fs/cgroup/cpu.max")
102
+ # cgroups v2: https://docs.kernel.org/admin-guide/cgroup-v2.html#cpu-interface-files
103
+ cpu_max = File.read("/sys/fs/cgroup/cpu.max")
104
+ return nil if cpu_max.start_with?("max ") # no limit
105
+ max, period = cpu_max.split.map(&:to_f)
106
+ max / period
107
+ elsif File.exist?("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us")
108
+ # cgroups v1: https://kernel.googlesource.com/pub/scm/linux/kernel/git/glommer/memcg/+/cpu_stat/Documentation/cgroups/cpu.txt
109
+ max = File.read("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us").to_i
110
+ return nil if max == 0
111
+ period = File.read("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us").to_f
112
+ max / period
113
+ end
114
+ end
115
+ end
63
116
  end
64
117
  end
65
118
 
@@ -107,4 +160,31 @@ module Concurrent
107
160
  def self.physical_processor_count
108
161
  processor_counter.physical_processor_count
109
162
  end
163
+
164
+ # 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).
167
+ #
168
+ # For performance reasons the calculated value will be memoized on the first
169
+ # call.
170
+ #
171
+ # @return [nil, Float] number of available processors
172
+ def self.available_processor_count
173
+ processor_counter.available_processor_count
174
+ end
175
+
176
+ # The maximum number of processors cores available for process scheduling.
177
+ # Returns `nil` if there is no enforced limit, or a `Float` if the
178
+ # process is inside a cgroup with a dedicated CPU quota (typically Docker).
179
+ #
180
+ # Note that nothing prevents setting a CPU quota higher than the actual number of
181
+ # cores on the system.
182
+ #
183
+ # For performance reasons the calculated value will be memoized on the first
184
+ # call.
185
+ #
186
+ # @return [nil, Float] Maximum number of available processors as set by a cgroup CPU quota, or nil if none set
187
+ def self.cpu_quota
188
+ processor_counter.cpu_quota
189
+ end
110
190
  end
@@ -1,3 +1,3 @@
1
1
  module Concurrent
2
- VERSION = '1.2.3'
2
+ VERSION = '1.3.3'
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.2.3
4
+ version: 1.3.3
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-01-16 00:00:00.000000000 Z
13
+ date: 2024-06-09 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.