producer-consumers 0.0.1

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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZWJiZDI1YmVkY2ZlYzc4NDAxMDYzZjdlYzI5ZWQzODAzZjliNzQyNQ==
5
+ data.tar.gz: !binary |-
6
+ ODdlM2MwODRlZDlhZjJjZjg5NzdhMzhiNmU1ZWQ3NjQ2NTcxNDg2YQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NjYxNjQ0OWI0OTI4N2I5YjliNWRlNWU5MWE5YjA4OTBjYTg1ZjM0MzFmMDU1
10
+ NjBjZGExMDk1ZTNjMzUwOTJkYmQ3NjRmZGQ2NDM3MTRhMTJjODJiMTQzMDNl
11
+ ZGQ3NTQxZGNmOTBjZDkzZmMwZGFkY2EzOTVjMjc2ZDNmY2UyN2E=
12
+ data.tar.gz: !binary |-
13
+ MWMxYTk1MTJkMjk2NTg4MzAxOTZmZmIwYzMyMmI1M2RjMzVkZWZmYjBhODYz
14
+ ZGU5OTM3ZjEzMDhhMzMxYWI0OTk5MWU4YzlhMzkwYWU2YmUxZDY0OTc5NmRj
15
+ ZjAwYmFkMTIwZmQ4YjI0YjI2ZGU1OTBhYjlkODRmNzhhOWQyM2E=
@@ -0,0 +1,69 @@
1
+ require 'thread'
2
+ class ProducerConsumers
3
+ DONE = Object.new
4
+
5
+ def self.run(enumerable, opts = {}, &block)
6
+ self.new(enumerable, opts).run!(&block)
7
+ end
8
+
9
+ def initialize(enumerable, opts = {})
10
+ opts = {
11
+ :size => 100,
12
+ :thread_count => 8,
13
+ }.merge opts
14
+ [:size, :thread_count, :begin, :end].each{|s| self.instance_variable_set "@#{s}", opts[s]}
15
+ @enum = enumerable.to_enum
16
+ end
17
+
18
+ def run!
19
+ @enum.rewind
20
+ queue = SizedQueue.new @size
21
+ dead_threads = Queue.new
22
+
23
+ producer = self.new_thread_with_morgue dead_threads do
24
+ loop do
25
+ begin
26
+ x = @enum.next
27
+ rescue StopIteration
28
+ queue << DONE
29
+ Thread.exit
30
+ end
31
+ queue << x
32
+ end # loop
33
+ end # thread
34
+
35
+ consumers = @thread_count.times.map do
36
+ self.new_thread_with_morgue dead_threads do
37
+ @begin and @begin.call
38
+ loop do
39
+ x = queue.shift
40
+ if x == DONE
41
+ queue << DONE
42
+ break
43
+ else
44
+ yield x
45
+ end
46
+ end # loop
47
+ @end and @end.call
48
+ end # thread
49
+ end
50
+
51
+ threads = consumers.unshift producer
52
+ live_thread_count = threads.size
53
+ until live_thread_count == 0 do # join all worker threads as soon as they finish
54
+ dead_threads.shift.join
55
+ live_thread_count -= 1
56
+ end
57
+ end
58
+
59
+ def new_thread_with_morgue(queue)
60
+ Thread.new do
61
+ begin
62
+ yield
63
+ ensure
64
+ queue << Thread.current
65
+ end
66
+ end
67
+ end
68
+
69
+ end
metadata ADDED
@@ -0,0 +1,44 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: producer-consumers
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chris Rogers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-06-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: ''
14
+ email: ''
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - /home/rcrogers/gems/producer-consumers/lib/producer-consumers.rb
20
+ homepage: https://github.com/rcrogers/producer-consumers
21
+ licenses: []
22
+ metadata: {}
23
+ post_install_message:
24
+ rdoc_options: []
25
+ require_paths:
26
+ - lib
27
+ required_ruby_version: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ! '>='
30
+ - !ruby/object:Gem::Version
31
+ version: '0'
32
+ required_rubygems_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ! '>='
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ requirements: []
38
+ rubyforge_project:
39
+ rubygems_version: 2.0.3
40
+ signing_key:
41
+ specification_version: 4
42
+ summary: ''
43
+ test_files: []
44
+ has_rdoc: