async_enum 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +1 -1
- data/async_enum.gemspec +1 -1
- data/lib/enumerator/async.rb +27 -3
- data/test/async_enum_test/benchmark_test.rb +0 -1
- data/test/async_enum_test/hash_compatible_test.rb +23 -0
- data/test/async_enum_test/thread_pool_test.rb +14 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZDFhMWYwZjQ0ZWE1Njc1NzJiZGU3ZTEwMDAyMzIzN2M4ZmZhZDM4ZA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZDAzNTI1ZjczYzU4NjQ0YTNhNTVmMTkzMzdjNzEyMzk4Y2Q4ZjUwMw==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YmQ0MjFmMTU3NGQyMWEzZTQ4MWY5NjM2NGZhMWVhN2Q0OTU4ZGY3ZTBhNDI3
|
10
|
+
NWUyNmQ1YzZlMWVkNjA0YmIwNWE5OTZhNTdhNzg1ZjUxZTdkZDkxZjUzMzM4
|
11
|
+
MDA5NmFhZGU3NzE5MTQyMGMzOTU3N2IzNTUxYzczMzgwMzcwNTE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZjdiNzk0OWI1MGI0YzE1MzE5NjExYzI4OTNjNGYzNmM1YzQ0ZmViODk0NTA0
|
14
|
+
OWMyZWUyNjQwOTY5MzdlYzEzZjc2OThjNWVhZGExYWE1MzI2MmQ4NTM4M2Zj
|
15
|
+
YmZlMmFhMjljNTk1ODVhYWIxZTY2MTIwOWUyNDQ3MmQ1ZjRkZDc=
|
data/README.md
CHANGED
data/async_enum.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = 'async_enum'
|
7
|
-
s.version = '0.0.
|
7
|
+
s.version = '0.0.5'
|
8
8
|
s.authors = %w(aj0strow)
|
9
9
|
s.email = 'alexander.ostrow@gmail.com'
|
10
10
|
s.description = 'iterate over enumerable objects concurrently'
|
data/lib/enumerator/async.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
1
3
|
class Enumerator
|
2
4
|
class Async < Enumerator
|
3
5
|
|
@@ -15,7 +17,18 @@ class Enumerator
|
|
15
17
|
alias_method :evaluate, :instance_exec
|
16
18
|
end
|
17
19
|
|
20
|
+
EOQ = Object.new
|
21
|
+
private_constant :EOQ
|
22
|
+
|
18
23
|
def initialize(enum, pool_size = nil)
|
24
|
+
if pool_size
|
25
|
+
unless pool_size >= 1
|
26
|
+
message = "Thread pool size is invalid! Expected a positive integer but got: #{pool_size}"
|
27
|
+
raise ArgumentError, message
|
28
|
+
end
|
29
|
+
pool_size = pool_size.to_i
|
30
|
+
end
|
31
|
+
|
19
32
|
@enum = enum
|
20
33
|
@pool_size = pool_size
|
21
34
|
@lockset = Lockset.new
|
@@ -39,13 +52,24 @@ class Enumerator
|
|
39
52
|
raise_error('each') unless block_given?
|
40
53
|
|
41
54
|
if @pool_size
|
55
|
+
queue = SizedQueue.new @pool_size
|
56
|
+
|
42
57
|
threads = @pool_size.times.map do
|
43
58
|
Thread.new do
|
44
59
|
loop do
|
45
|
-
|
60
|
+
item = queue.pop
|
61
|
+
item != EOQ ? evaluate(item, &work) : break
|
46
62
|
end
|
47
63
|
end
|
48
64
|
end
|
65
|
+
|
66
|
+
begin
|
67
|
+
loop { queue.push @enum.next }
|
68
|
+
rescue StopIteration
|
69
|
+
ensure
|
70
|
+
@pool_size.times { queue.push EOQ }
|
71
|
+
end
|
72
|
+
|
49
73
|
threads.each(&:join)
|
50
74
|
@enum.rewind
|
51
75
|
else
|
@@ -99,8 +123,8 @@ class Enumerator
|
|
99
123
|
end
|
100
124
|
|
101
125
|
def raise_error(method)
|
102
|
-
raise ArgumentError, "
|
126
|
+
raise ArgumentError, "Tried to call async #{method} without a block"
|
103
127
|
end
|
104
128
|
|
105
129
|
end
|
106
|
-
end
|
130
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class HashCompatibleTest < Test
|
4
|
+
|
5
|
+
setup do
|
6
|
+
@hash = { a: 1, b: 2 }
|
7
|
+
end
|
8
|
+
|
9
|
+
test 'hash compatible unlimited' do
|
10
|
+
values = @hash.async.map do |key, value|
|
11
|
+
[key, value * 2]
|
12
|
+
end
|
13
|
+
assert_equal [[:a, 2], [:b, 4]], values
|
14
|
+
end
|
15
|
+
|
16
|
+
test 'hash compatible' do
|
17
|
+
values = @hash.async(2).map do |key, value|
|
18
|
+
[key, value * 2]
|
19
|
+
end
|
20
|
+
assert_equal [[:a, 2], [:b, 4]], values
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -21,4 +21,17 @@ class ThreadPoolTest < Test
|
|
21
21
|
assert_equal [2, 3, 4, 5, 6, 7, 8, 9], vals
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
test 'pools with hash' do
|
25
|
+
values = { a: 1, b: 2 }.async(2).map do |key, value|
|
26
|
+
[key, value * 2]
|
27
|
+
end
|
28
|
+
assert_equal [[:a, 2], [:b, 4]], values
|
29
|
+
end
|
30
|
+
|
31
|
+
test 'doesnt throw fiber error' do
|
32
|
+
# implicitly will fail if error is raised
|
33
|
+
5.times.async(2).each { sleep 0.00001 }
|
34
|
+
assert true
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async_enum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aj0strow
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-10-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -59,6 +59,7 @@ files:
|
|
59
59
|
- test/async_enum_test/benchmark_test.rb
|
60
60
|
- test/async_enum_test/definitions_test.rb
|
61
61
|
- test/async_enum_test/enumerator_async_test.rb
|
62
|
+
- test/async_enum_test/hash_compatible_test.rb
|
62
63
|
- test/async_enum_test/thread_pool_test.rb
|
63
64
|
- test/test_helper.rb
|
64
65
|
homepage: http://github.com/aj0strow/async_enum
|
@@ -89,5 +90,6 @@ test_files:
|
|
89
90
|
- test/async_enum_test/benchmark_test.rb
|
90
91
|
- test/async_enum_test/definitions_test.rb
|
91
92
|
- test/async_enum_test/enumerator_async_test.rb
|
93
|
+
- test/async_enum_test/hash_compatible_test.rb
|
92
94
|
- test/async_enum_test/thread_pool_test.rb
|
93
95
|
- test/test_helper.rb
|