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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MWU0MWNjY2UwYTE3OTI5Njc1OThiZTAyMDNjMjliNmQ3MWMzZmZjMg==
4
+ ZDFhMWYwZjQ0ZWE1Njc1NzJiZGU3ZTEwMDAyMzIzN2M4ZmZhZDM4ZA==
5
5
  data.tar.gz: !binary |-
6
- NGM5ZDA0NjA5NTI3M2YyNjVjZTA1N2UxOTVmYzI5MGQ2OGQ5YzhlNg==
6
+ ZDAzNTI1ZjczYzU4NjQ0YTNhNTVmMTkzMzdjNzEyMzk4Y2Q4ZjUwMw==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MjQ0Nzc5NmVlNTQzMzMzZmEyNzBmOTU4ZThkYWZmOWYwYmFmYTUxMDkxMTU5
10
- NTFhNzI0MTUxNDQ2NGIyZjU3OTAyMTFiZTFiZjdmZjNlYWNhMGVlYjdkNTY2
11
- OGFmZWM4OTk4MzUyNGUwYTQ3YWQ1N2Q3YjZjYWU2NjFkMmNlNTc=
9
+ YmQ0MjFmMTU3NGQyMWEzZTQ4MWY5NjM2NGZhMWVhN2Q0OTU4ZGY3ZTBhNDI3
10
+ NWUyNmQ1YzZlMWVkNjA0YmIwNWE5OTZhNTdhNzg1ZjUxZTdkZDkxZjUzMzM4
11
+ MDA5NmFhZGU3NzE5MTQyMGMzOTU3N2IzNTUxYzczMzgwMzcwNTE=
12
12
  data.tar.gz: !binary |-
13
- MWQyYWM1ZWQ1ODc1YjQ0M2M2Y2VhMjQzM2I5ODhiODU0MjEzOTdmNzM0ZTY2
14
- ZDcwMTE5YjhlYTEwZmUwMDBlMmE5MTI0MWY4MGU3ZWNlOTMxMzlhN2ZhOWIy
15
- M2ExYjE1ZWI2MjM0MjBkMGM3ZTY1YWFiNDhjNmIwNmNmZWYzOTk=
13
+ ZjdiNzk0OWI1MGI0YzE1MzE5NjExYzI4OTNjNGYzNmM1YzQ0ZmViODk0NTA0
14
+ OWMyZWUyNjQwOTY5MzdlYzEzZjc2OThjNWVhZGExYWE1MzI2MmQ4NTM4M2Zj
15
+ YmZlMmFhMjljNTk1ODVhYWIxZTY2MTIwOWUyNDQ3MmQ1ZjRkZDc=
data/README.md CHANGED
@@ -105,7 +105,7 @@ To install it, add it to your gemfile:
105
105
  ```
106
106
  # Gemfile
107
107
 
108
- gem 'async_enum', github: 'aj0strow/async_enum'
108
+ gem 'async_enum'
109
109
  ```
110
110
 
111
111
  To run the demos, clone the project and run with the library included in the load path:
@@ -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.4'
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'
@@ -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
- @enum.any? ? evaluate(*@enum.next, &work) : break
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, "tried to call async #{method} without a block"
126
+ raise ArgumentError, "Tried to call async #{method} without a block"
103
127
  end
104
128
 
105
129
  end
106
- end
130
+ end
@@ -8,5 +8,4 @@ class BenchmarkTest < Test
8
8
  end
9
9
  end
10
10
 
11
-
12
11
  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
- end
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
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-07-19 00:00:00.000000000 Z
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