in_threads 1.5.1 → 1.6.0
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/.github/workflows/check.yml +51 -0
- data/.github/workflows/rubocop.yml +16 -0
- data/.rubocop.yml +20 -9
- data/CHANGELOG.markdown +19 -0
- data/Gemfile +2 -4
- data/LICENSE.txt +1 -1
- data/README.markdown +23 -12
- data/in_threads.gemspec +5 -6
- data/lib/in_threads.rb +46 -19
- data/spec/in_threads_spec.rb +57 -19
- metadata +34 -13
- data/.travis.yml +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ab96a79a5ad21d6198f4c91e689a37343371ca5932a30d695c91f8f8949a9c5
|
4
|
+
data.tar.gz: 91e41ba4f9073cff55f925e40cbc8728893974ec365a440b1f57cafd315ce4be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c03797c1506c3bc73b1fd8191ba931f21c63c30e56a897bc309815a461eaa2baa368e7daa88a2023113c954c1016666f0b267cfa11b01455d59b3af4d0999f7
|
7
|
+
data.tar.gz: 274d7a37b752f0f673eb575a348422999b177cdd56e9519f11dbbee0305bd16b17aceccdfd08f1c2ba12b46c8119a309e1a4cc88f8ff3be6078940dc579f96f0
|
@@ -0,0 +1,51 @@
|
|
1
|
+
name: check
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
pull_request:
|
5
|
+
schedule:
|
6
|
+
- cron: 45 4 * * 3
|
7
|
+
jobs:
|
8
|
+
check:
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
strategy:
|
11
|
+
matrix:
|
12
|
+
ruby:
|
13
|
+
- '2.0'
|
14
|
+
- '2.1'
|
15
|
+
- '2.2'
|
16
|
+
- '2.3'
|
17
|
+
- '2.4'
|
18
|
+
- '2.5'
|
19
|
+
- '2.6'
|
20
|
+
- '2.7'
|
21
|
+
- '3.0'
|
22
|
+
- '3.1'
|
23
|
+
- jruby-9.1
|
24
|
+
- jruby-9.2
|
25
|
+
- jruby-9.3
|
26
|
+
include:
|
27
|
+
- ruby: ruby-head
|
28
|
+
allow-failure: allow-failure
|
29
|
+
fail-fast: false
|
30
|
+
continue-on-error: ${{ matrix.allow-failure && true || false }}
|
31
|
+
timeout-minutes: 5
|
32
|
+
steps:
|
33
|
+
- uses: actions/checkout@v2
|
34
|
+
- uses: ruby/setup-ruby@v1
|
35
|
+
with:
|
36
|
+
ruby-version: "${{ matrix.ruby }}"
|
37
|
+
bundler-cache: true
|
38
|
+
- run: bundle exec rspec --format documentation
|
39
|
+
legacy:
|
40
|
+
runs-on: ubuntu-latest
|
41
|
+
container: ${{ matrix.container }}
|
42
|
+
strategy:
|
43
|
+
matrix:
|
44
|
+
container:
|
45
|
+
- rspec/ci:1.8.7
|
46
|
+
- rspec/ci:1.9.3
|
47
|
+
fail-fast: false
|
48
|
+
steps:
|
49
|
+
- uses: actions/checkout@v2
|
50
|
+
- run: bundle install
|
51
|
+
- run: bundle exec rspec --format documentation
|
@@ -0,0 +1,16 @@
|
|
1
|
+
name: rubocop
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
pull_request:
|
5
|
+
schedule:
|
6
|
+
- cron: 45 4 * * 3
|
7
|
+
jobs:
|
8
|
+
rubocop:
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
steps:
|
11
|
+
- uses: actions/checkout@v2
|
12
|
+
- uses: ruby/setup-ruby@v1
|
13
|
+
with:
|
14
|
+
ruby-version: '3.1'
|
15
|
+
bundler-cache: true
|
16
|
+
- run: bundle exec rubocop
|
data/.rubocop.yml
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
AllCops:
|
2
2
|
Exclude:
|
3
3
|
- '*.gemspec'
|
4
|
+
- 'vendor/bundle/**/*'
|
5
|
+
NewCops: enable
|
4
6
|
|
5
7
|
Layout/AccessModifierIndentation:
|
6
8
|
EnforcedStyle: outdent
|
@@ -14,9 +16,12 @@ Layout/DotPosition:
|
|
14
16
|
Layout/EndAlignment:
|
15
17
|
EnforcedStyleAlignWith: variable
|
16
18
|
|
17
|
-
Layout/
|
19
|
+
Layout/FirstHashElementIndentation:
|
18
20
|
EnforcedStyle: consistent
|
19
21
|
|
22
|
+
Layout/LineLength:
|
23
|
+
Max: 120
|
24
|
+
|
20
25
|
Layout/RescueEnsureAlignment:
|
21
26
|
Enabled: false
|
22
27
|
|
@@ -33,10 +38,10 @@ Lint/AmbiguousBlockAssociation:
|
|
33
38
|
Lint/EnsureReturn:
|
34
39
|
Enabled: false
|
35
40
|
|
36
|
-
Lint/
|
41
|
+
Lint/RedundantRequireStatement:
|
37
42
|
Enabled: false
|
38
43
|
|
39
|
-
Lint/
|
44
|
+
Lint/RescueException:
|
40
45
|
Enabled: false
|
41
46
|
|
42
47
|
Metrics/AbcSize:
|
@@ -52,24 +57,30 @@ Metrics/ClassLength:
|
|
52
57
|
Metrics/CyclomaticComplexity:
|
53
58
|
Max: 10
|
54
59
|
|
55
|
-
Metrics/LineLength:
|
56
|
-
Max: 120
|
57
|
-
|
58
60
|
Metrics/MethodLength:
|
59
61
|
Max: 30
|
60
62
|
|
61
|
-
Performance/RedundantBlockCall:
|
62
|
-
Enabled: false
|
63
|
-
|
64
63
|
Style/DoubleNegation:
|
65
64
|
Enabled: false
|
66
65
|
|
66
|
+
Style/HashEachMethods:
|
67
|
+
Enabled: true
|
68
|
+
|
67
69
|
Style/HashSyntax:
|
68
70
|
EnforcedStyle: hash_rockets
|
69
71
|
|
72
|
+
Style/HashTransformKeys:
|
73
|
+
Enabled: false
|
74
|
+
|
75
|
+
Style/HashTransformValues:
|
76
|
+
Enabled: false
|
77
|
+
|
70
78
|
Style/IfUnlessModifier:
|
71
79
|
Enabled: false
|
72
80
|
|
81
|
+
Style/OptionalBooleanParameter:
|
82
|
+
Enabled: false
|
83
|
+
|
73
84
|
Style/ParallelAssignment:
|
74
85
|
Enabled: false
|
75
86
|
|
data/CHANGELOG.markdown
CHANGED
@@ -2,6 +2,25 @@
|
|
2
2
|
|
3
3
|
## unreleased
|
4
4
|
|
5
|
+
## v1.6.0 (2022-01-18)
|
6
|
+
|
7
|
+
* Fix return for shortcut `enum.in_threads{ break … }` vs `enum.in_threads.each{ break … }` [@toy](https://github.com/toy)
|
8
|
+
* Switch `each_with_object` to run in threads, unlike inject/reduce there is no contradiction, care should be taken if passed object is not thread safe [@toy](https://github.com/toy)
|
9
|
+
* Switch `to_h` (ruby >= 2.6) and `to_set` to run in threads, they accept block to apply before creating Hash and Set respectively [@toy](https://github.com/toy)
|
10
|
+
* Register `compact` added in 3.1 to run without threads (as it doesn't accept block) [@toy](https://github.com/toy)
|
11
|
+
|
12
|
+
## v1.5.4 (2019-12-26)
|
13
|
+
|
14
|
+
* Register `filter_map` to run in threads and `tally` to run without threads (as it doesn't accept block) [@toy](https://github.com/toy)
|
15
|
+
|
16
|
+
## v1.5.3 (2019-07-14)
|
17
|
+
|
18
|
+
* Remove deprecated `rubyforge_project` attribute from gemspec [rubygems/rubygems#2436](https://github.com/rubygems/rubygems/pull/2436) [@toy](https://github.com/toy)
|
19
|
+
|
20
|
+
## v1.5.2 (2019-05-25)
|
21
|
+
|
22
|
+
* Enable frozen string literals [@toy](https://github.com/toy)
|
23
|
+
|
5
24
|
## v1.5.1 (2018-12-30)
|
6
25
|
|
7
26
|
* Register `chain` to run without threads [@toy](https://github.com/toy)
|
data/Gemfile
CHANGED
data/LICENSE.txt
CHANGED
data/README.markdown
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
[](https://rubygems.org/gems/in_threads)
|
2
|
+
[](https://github.com/toy/in_threads/actions/workflows/check.yml)
|
3
|
+
[](https://codeclimate.com/github/toy/in_threads)
|
4
|
+
[](https://depfu.com/github/toy/in_threads)
|
5
|
+
[](https://inch-ci.org/github/toy/in_threads)
|
6
6
|
|
7
7
|
# in_threads
|
8
8
|
|
@@ -25,13 +25,13 @@ gem 'in_threads'
|
|
25
25
|
...and install it with [Bundler](http://bundler.io).
|
26
26
|
|
27
27
|
```sh
|
28
|
-
|
28
|
+
bundle install
|
29
29
|
```
|
30
30
|
|
31
31
|
Or install globally:
|
32
32
|
|
33
33
|
```sh
|
34
|
-
|
34
|
+
gem install in_threads
|
35
35
|
```
|
36
36
|
|
37
37
|
## Usage
|
@@ -90,9 +90,20 @@ urls.in_threads.all? { |url| HTTP.get(url).status == 200 }
|
|
90
90
|
urls.in_threads.any? { |url| HTTP.get(url).status == 404 }
|
91
91
|
```
|
92
92
|
|
93
|
-
|
94
|
-
|
95
|
-
|
93
|
+
### Compatibility
|
94
|
+
|
95
|
+
All methods of `Enumerable` with a block can be used if block calls are evaluated independently, so following will
|
96
|
+
|
97
|
+
`all?`, `any?`, `collect_concat`, `collect`, `count`, `cycle`, `detect`, `drop_while`, `each_cons`, `each_entry`,
|
98
|
+
`each_slice`, `each_with_index`, `each_with_object`, `each`, `enum_cons`, `enum_slice`, `enum_with_index`,
|
99
|
+
`filter_map`, `filter`, `find_all`, `find_index`, `find`, `flat_map`, `group_by`, `map`, `max_by`, `min_by`,
|
100
|
+
`minmax_by`, `none?`, `one?`, `partition`, `reject`, `reverse_each`, `select`, `sort_by`, `sum`, `take_while`, `to_h`,
|
101
|
+
`to_set`, `uniq`, `zip`.
|
102
|
+
|
103
|
+
Following either don't accept block (like `first`), depend on previous block evaluation (like `inject`) or return an enumerator (like `chunk`), so will simply act as if `in_threads` wasn't used:
|
104
|
+
|
105
|
+
`chain`, `chunk_while`, `chunk`, `compact`, `drop`, `entries`, `first`, `include?`, `inject`, `lazy`, `max`, `member?`,
|
106
|
+
`minmax`, `min`, `reduce`, `slice_after`, `slice_before`, `slice_when`, `sort`, `take`, `tally`, `to_a`.
|
96
107
|
|
97
108
|
### Break and exceptions
|
98
109
|
|
@@ -100,8 +111,8 @@ Exceptions are caught and re-thrown after allowing blocks that are still running
|
|
100
111
|
|
101
112
|
**IMPORTANT**: only the first encountered exception is propagated, so it is recommended to handle exceptions in the block.
|
102
113
|
|
103
|
-
`break` is handled in ruby >= 1.9 and should be handled in jruby [after 9.1.9.0](https://github.com/jruby/jruby/issues/4697). Handling is done in special way: as blocks are run outside of original context, calls to `break` cause `LocalJumpError` which is caught and its result is returned.
|
114
|
+
`break` is handled in ruby >= 1.9 and should be handled in jruby [9.1 after 9.1.9.0](https://github.com/jruby/jruby/issues/4697) and [9.2 and 9.3 after #7009](https://github.com/jruby/jruby/issues/7009). Handling is done in special way: as blocks are run outside of original context, calls to `break` cause `LocalJumpError` which is caught and its result is returned.
|
104
115
|
|
105
116
|
## Copyright
|
106
117
|
|
107
|
-
Copyright (c) 2009-
|
118
|
+
Copyright (c) 2009-2022 Ivan Kuchin. See LICENSE.txt for details.
|
data/in_threads.gemspec
CHANGED
@@ -2,14 +2,12 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'in_threads'
|
5
|
-
s.version = '1.
|
5
|
+
s.version = '1.6.0'
|
6
6
|
s.summary = %q{Run all possible enumerable methods in concurrent/parallel threads}
|
7
|
-
s.homepage = "
|
7
|
+
s.homepage = "https://github.com/toy/#{s.name}"
|
8
8
|
s.authors = ['Ivan Kuchin']
|
9
9
|
s.license = 'MIT'
|
10
10
|
|
11
|
-
s.rubyforge_project = s.name
|
12
|
-
|
13
11
|
s.metadata = {
|
14
12
|
'bug_tracker_uri' => "https://github.com/toy/#{s.name}/issues",
|
15
13
|
'changelog_uri' => "https://github.com/toy/#{s.name}/blob/master/CHANGELOG.markdown",
|
@@ -24,7 +22,8 @@ Gem::Specification.new do |s|
|
|
24
22
|
|
25
23
|
s.add_development_dependency 'rspec', '~> 3.0'
|
26
24
|
s.add_development_dependency 'rspec-retry', '~> 0.3'
|
27
|
-
if RUBY_VERSION >= '2.
|
28
|
-
s.add_development_dependency 'rubocop', '~>
|
25
|
+
if RUBY_VERSION >= '2.5'
|
26
|
+
s.add_development_dependency 'rubocop', '~> 1.22', '!= 1.22.2'
|
27
|
+
s.add_development_dependency 'rubocop-rspec', '~> 2.0'
|
29
28
|
end
|
30
29
|
end
|
data/lib/in_threads.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'thread'
|
2
4
|
require 'delegate'
|
5
|
+
require 'set'
|
3
6
|
|
4
7
|
Enumerable.class_eval do
|
5
8
|
# Run enumerable method blocks in threads
|
@@ -31,17 +34,23 @@ class InThreads < SimpleDelegator
|
|
31
34
|
protected :__getobj__, :__setobj__
|
32
35
|
|
33
36
|
attr_reader :enumerable, :thread_count
|
34
|
-
|
37
|
+
|
38
|
+
def self.new(enumerable, thread_count = 10, &block)
|
39
|
+
if block
|
40
|
+
super.each(&block)
|
41
|
+
else
|
42
|
+
super
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize(enumerable, thread_count = 10)
|
35
47
|
super(enumerable)
|
48
|
+
|
36
49
|
@enumerable, @thread_count = enumerable, thread_count.to_i
|
37
|
-
unless enumerable.is_a?(Enumerable)
|
38
|
-
fail ArgumentError, '`enumerable` should include Enumerable.'
|
39
|
-
end
|
40
|
-
if thread_count < 2
|
41
|
-
fail ArgumentError, '`thread_count` can\'t be less than 2.'
|
42
|
-
end
|
43
50
|
|
44
|
-
|
51
|
+
fail ArgumentError, '`enumerable` should include Enumerable.' unless enumerable.is_a?(Enumerable)
|
52
|
+
|
53
|
+
fail ArgumentError, '`thread_count` can\'t be less than 2.' if thread_count < 2
|
45
54
|
end
|
46
55
|
|
47
56
|
# Creates new instance using underlying enumerable and new thread_count
|
@@ -66,13 +75,13 @@ class InThreads < SimpleDelegator
|
|
66
75
|
next if ignore_undefined && !enumerable_method?(method)
|
67
76
|
|
68
77
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
69
|
-
def #{method}(*args, &block)
|
70
|
-
if block
|
71
|
-
#{runner}(:#{method}, *args, &block)
|
72
|
-
else
|
73
|
-
enumerable.#{method}(*args)
|
74
|
-
end
|
75
|
-
end
|
78
|
+
def #{method}(*args, &block) # def foo_bar(*args, &block)
|
79
|
+
if block # if block
|
80
|
+
#{runner}(:#{method}, *args, &block) # run_in_threads_method(:foo_bar, *args, &block)
|
81
|
+
else # else
|
82
|
+
enumerable.#{method}(*args) # enumerable.foo_bar(*args)
|
83
|
+
end # end
|
84
|
+
end # end
|
76
85
|
RUBY
|
77
86
|
end
|
78
87
|
end
|
@@ -92,6 +101,7 @@ class InThreads < SimpleDelegator
|
|
92
101
|
zip
|
93
102
|
cycle
|
94
103
|
each_entry
|
104
|
+
each_with_object
|
95
105
|
], :ignore_undefined => true
|
96
106
|
use :run_in_threads_use_block_result, :for => %w[
|
97
107
|
all? any? none? one?
|
@@ -99,21 +109,38 @@ class InThreads < SimpleDelegator
|
|
99
109
|
partition find_all select filter reject count
|
100
110
|
collect map group_by max_by min_by minmax_by sort_by sum uniq
|
101
111
|
flat_map collect_concat
|
112
|
+
filter_map
|
113
|
+
to_set
|
102
114
|
], :ignore_undefined => true
|
103
115
|
|
104
|
-
|
116
|
+
DEPENDENT_BLOCK_CALLS = %w[
|
105
117
|
inject reduce
|
106
118
|
max min minmax sort
|
107
|
-
|
119
|
+
].map(&:to_sym)
|
120
|
+
|
121
|
+
ENUMERATOR_RETURNED = %w[
|
122
|
+
chunk chunk_while slice_before slice_after slice_when
|
123
|
+
].map(&:to_sym)
|
124
|
+
|
125
|
+
BLOCKLESS_METHODS = %w[
|
126
|
+
entries to_a
|
108
127
|
drop take
|
109
128
|
first
|
110
129
|
include? member?
|
111
|
-
each_with_object
|
112
|
-
chunk chunk_while slice_before slice_after slice_when
|
113
130
|
lazy
|
114
131
|
chain
|
132
|
+
tally
|
133
|
+
compact
|
115
134
|
].map(&:to_sym)
|
116
135
|
|
136
|
+
if enumerable_method?(:to_h) && [[0, 0]].to_h{ [1, 1] } == {1 => 1}
|
137
|
+
use :run_in_threads_use_block_result, :for => %w[to_h]
|
138
|
+
else
|
139
|
+
BLOCKLESS_METHODS << :to_h
|
140
|
+
end
|
141
|
+
|
142
|
+
INCOMPATIBLE_METHODS = DEPENDENT_BLOCK_CALLS + ENUMERATOR_RETURNED + BLOCKLESS_METHODS
|
143
|
+
|
117
144
|
# Special case method, works by applying `run_in_threads_use_block_result` with
|
118
145
|
# map on enumerable returned by blockless run
|
119
146
|
def grep(*args, &block)
|
data/spec/in_threads_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rspec'
|
2
4
|
require 'rspec/retry'
|
3
5
|
require 'in_threads'
|
@@ -16,7 +18,12 @@ end
|
|
16
18
|
# not in jruby in mri < 1.9
|
17
19
|
# https://github.com/jruby/jruby/issues/4697
|
18
20
|
SKIP_IF_BREAK_IN_THREAD_IS_IGNORED = begin
|
19
|
-
|
21
|
+
proc do |&block|
|
22
|
+
Thread.new do
|
23
|
+
Thread.current.report_on_exception = false if Thread.current.respond_to?(:report_on_exception=)
|
24
|
+
block.call
|
25
|
+
end.join
|
26
|
+
end.call{ break } # rubocop:disable Style/MultilineBlockChain
|
20
27
|
'can not handle break in thread'
|
21
28
|
rescue LocalJumpError
|
22
29
|
false
|
@@ -140,6 +147,13 @@ describe InThreads do
|
|
140
147
|
end
|
141
148
|
|
142
149
|
describe 'exception/break handling' do
|
150
|
+
it 'returns identical to each when initialized with block', :skip => SKIP_IF_BREAK_IN_THREAD_IS_IGNORED do
|
151
|
+
v = double
|
152
|
+
expect(enum.each{ break v }).to eq(v) # rubocop:disable Lint/UnreachableLoop
|
153
|
+
expect(enum.in_threads{ break v }).to eq(v)
|
154
|
+
expect(enum.in_threads.each{ break v }).to eq(v) # rubocop:disable Lint/UnreachableLoop
|
155
|
+
end
|
156
|
+
|
143
157
|
%w[each map all?].each do |method|
|
144
158
|
describe "for ##{method}" do
|
145
159
|
it 'passes exception raised in block' do
|
@@ -151,7 +165,7 @@ describe InThreads do
|
|
151
165
|
fail 'expected'
|
152
166
|
end
|
153
167
|
|
154
|
-
expect{ enum.in_threads.send(method){} }.to raise_error('expected')
|
168
|
+
expect{ enum.in_threads.send(method){ nil } }.to raise_error('expected')
|
155
169
|
end
|
156
170
|
|
157
171
|
it 'handles break', :skip => SKIP_IF_BREAK_IN_THREAD_IS_IGNORED do
|
@@ -203,15 +217,18 @@ describe InThreads do
|
|
203
217
|
context 'exception order' do
|
204
218
|
before do
|
205
219
|
stub_const('Order', Queue.new)
|
220
|
+
def Order.releasing
|
221
|
+
fail 'expected'
|
222
|
+
ensure
|
223
|
+
push nil
|
224
|
+
end
|
206
225
|
end
|
207
226
|
|
208
227
|
it 'passes exception raised during iteration if it happens earlier than in block' do
|
209
228
|
def enum.each(&block)
|
210
229
|
5.times(&block)
|
211
|
-
|
230
|
+
Order.releasing do
|
212
231
|
fail 'expected'
|
213
|
-
ensure
|
214
|
-
Order.push nil
|
215
232
|
end
|
216
233
|
end
|
217
234
|
|
@@ -234,10 +251,8 @@ describe InThreads do
|
|
234
251
|
|
235
252
|
expect do
|
236
253
|
enum.in_threads(10).send(method) do
|
237
|
-
|
254
|
+
Order.releasing do
|
238
255
|
fail 'expected'
|
239
|
-
ensure
|
240
|
-
Order.push nil
|
241
256
|
end
|
242
257
|
end
|
243
258
|
end.to raise_error('expected')
|
@@ -247,10 +262,8 @@ describe InThreads do
|
|
247
262
|
expect do
|
248
263
|
enum.in_threads(10).send(method) do |i|
|
249
264
|
if i == 5
|
250
|
-
|
265
|
+
Order.releasing do
|
251
266
|
fail 'expected'
|
252
|
-
ensure
|
253
|
-
Order.push nil
|
254
267
|
end
|
255
268
|
else
|
256
269
|
Thread.pass while Order.empty?
|
@@ -509,8 +522,13 @@ describe InThreads do
|
|
509
522
|
collect map
|
510
523
|
group_by max_by min_by minmax_by sort_by
|
511
524
|
sum uniq
|
525
|
+
to_h to_set
|
512
526
|
].each do |method|
|
527
|
+
next if method == 'to_h' && InThreads::INCOMPATIBLE_METHODS.include?(:to_h)
|
528
|
+
|
513
529
|
describe_enum_method method do
|
530
|
+
let(:value_proc){ proc{ [rand] * 2 } } if method == 'to_h'
|
531
|
+
|
514
532
|
it 'returns same result with threads' do
|
515
533
|
expect(enum.in_threads.send(method, &:compute)).
|
516
534
|
to eq(enum.send(method, &:compute))
|
@@ -716,6 +734,34 @@ describe InThreads do
|
|
716
734
|
end
|
717
735
|
end
|
718
736
|
end
|
737
|
+
|
738
|
+
describe_enum_method :each_with_object do
|
739
|
+
let(:block) do
|
740
|
+
proc do |o, h|
|
741
|
+
v = o.compute
|
742
|
+
mutex.synchronize{ h[v] = true }
|
743
|
+
end
|
744
|
+
end
|
745
|
+
|
746
|
+
it 'returns same result with threads' do
|
747
|
+
expect(enum.in_threads.each_with_object({}, &block)).
|
748
|
+
to eq(enum.each_with_object({}, &block))
|
749
|
+
end
|
750
|
+
|
751
|
+
it 'yields same objects' do
|
752
|
+
yielded = []
|
753
|
+
enum.in_threads.each_with_object({}) do |o, _h|
|
754
|
+
mutex.synchronize{ yielded << o }
|
755
|
+
o.compute
|
756
|
+
end
|
757
|
+
expect(yielded).to match_array(items)
|
758
|
+
end
|
759
|
+
|
760
|
+
it 'runs faster with threads', :flaky do
|
761
|
+
expect{ enum.in_threads.each_with_object({}, &block) }.
|
762
|
+
to be_faster_than{ enum.each_with_object({}, &block) }
|
763
|
+
end
|
764
|
+
end
|
719
765
|
end
|
720
766
|
|
721
767
|
context 'unthreaded' do
|
@@ -774,14 +820,6 @@ describe InThreads do
|
|
774
820
|
end
|
775
821
|
end
|
776
822
|
|
777
|
-
describe_enum_method :each_with_object do
|
778
|
-
let(:block){ proc{ |o, h| h[o] = true } }
|
779
|
-
|
780
|
-
it 'returns same result' do
|
781
|
-
expect(enum.in_threads.each_with_object({}, &block)).to eq(enum.each_with_object({}, &block))
|
782
|
-
end
|
783
|
-
end
|
784
|
-
|
785
823
|
%w[chunk slice_before slice_after].each do |method|
|
786
824
|
describe_enum_method method do
|
787
825
|
it 'returns same result' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: in_threads
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Kuchin
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -44,23 +44,44 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '1.22'
|
48
|
+
- - "!="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 1.22.2
|
51
|
+
type: :development
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - "~>"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '1.22'
|
58
|
+
- - "!="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 1.22.2
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rubocop-rspec
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '2.0'
|
48
68
|
type: :development
|
49
69
|
prerelease: false
|
50
70
|
version_requirements: !ruby/object:Gem::Requirement
|
51
71
|
requirements:
|
52
72
|
- - "~>"
|
53
73
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0
|
55
|
-
description:
|
56
|
-
email:
|
74
|
+
version: '2.0'
|
75
|
+
description:
|
76
|
+
email:
|
57
77
|
executables: []
|
58
78
|
extensions: []
|
59
79
|
extra_rdoc_files: []
|
60
80
|
files:
|
81
|
+
- ".github/workflows/check.yml"
|
82
|
+
- ".github/workflows/rubocop.yml"
|
61
83
|
- ".gitignore"
|
62
84
|
- ".rubocop.yml"
|
63
|
-
- ".travis.yml"
|
64
85
|
- CHANGELOG.markdown
|
65
86
|
- Gemfile
|
66
87
|
- LICENSE.txt
|
@@ -68,15 +89,15 @@ files:
|
|
68
89
|
- in_threads.gemspec
|
69
90
|
- lib/in_threads.rb
|
70
91
|
- spec/in_threads_spec.rb
|
71
|
-
homepage:
|
92
|
+
homepage: https://github.com/toy/in_threads
|
72
93
|
licenses:
|
73
94
|
- MIT
|
74
95
|
metadata:
|
75
96
|
bug_tracker_uri: https://github.com/toy/in_threads/issues
|
76
97
|
changelog_uri: https://github.com/toy/in_threads/blob/master/CHANGELOG.markdown
|
77
|
-
documentation_uri: https://www.rubydoc.info/gems/in_threads/1.
|
98
|
+
documentation_uri: https://www.rubydoc.info/gems/in_threads/1.6.0
|
78
99
|
source_code_uri: https://github.com/toy/in_threads
|
79
|
-
post_install_message:
|
100
|
+
post_install_message:
|
80
101
|
rdoc_options: []
|
81
102
|
require_paths:
|
82
103
|
- lib
|
@@ -91,8 +112,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
112
|
- !ruby/object:Gem::Version
|
92
113
|
version: '0'
|
93
114
|
requirements: []
|
94
|
-
rubygems_version: 3.
|
95
|
-
signing_key:
|
115
|
+
rubygems_version: 3.3.5
|
116
|
+
signing_key:
|
96
117
|
specification_version: 4
|
97
118
|
summary: Run all possible enumerable methods in concurrent/parallel threads
|
98
119
|
test_files:
|
data/.travis.yml
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
sudo: false
|
2
|
-
language: ruby
|
3
|
-
rvm:
|
4
|
-
- '1.8.7-p371'
|
5
|
-
- '1.9.3-p551'
|
6
|
-
- '2.0.0-p648'
|
7
|
-
- '2.1.10'
|
8
|
-
- '2.2.10'
|
9
|
-
- '2.3.8'
|
10
|
-
- '2.4.5'
|
11
|
-
- '2.5.3'
|
12
|
-
- '2.6.0'
|
13
|
-
- 'ruby-head'
|
14
|
-
- 'jruby-9.0.5.0'
|
15
|
-
- 'jruby-9.1.9.0'
|
16
|
-
before_install:
|
17
|
-
- gem install bundler
|
18
|
-
- ruby -e 'require "rubygems"; require "bundler/inline"; gemfile{ source "https://rubygems.org"; gem "rubygems-update" }' # get compatible version of rubygems-update
|
19
|
-
- gem update --system
|
20
|
-
script: bundle exec rspec
|
21
|
-
matrix:
|
22
|
-
include:
|
23
|
-
- env: RUBOCOP=✓
|
24
|
-
rvm: '2.5.3'
|
25
|
-
script: bundle exec rubocop
|
26
|
-
- env: CHECK_RUBIES=✓
|
27
|
-
rvm: '2.5.3'
|
28
|
-
script: bundle exec travis_check_rubies
|
29
|
-
allow_failures:
|
30
|
-
- rvm: 'ruby-head'
|