async_enum 0.0.4 → 0.0.5

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,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