ruby_thread_pool 0.1.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.
@@ -0,0 +1,59 @@
1
+ require "thread"
2
+
3
+ class ThreadPool
4
+ def initialize(pool_size)
5
+ @pool = []
6
+ @pool_size = pool_size
7
+ @pool_mutex = Mutex.new
8
+ @pool_cv = ConditionVariable.new
9
+ end
10
+
11
+ def run(*args)
12
+ Thread.new do
13
+ @pool_mutex.synchronize do
14
+ while @pool.size >= @pool_size
15
+ print "Pool is full: waiting to run #{args.join(",")}\n" if $DEBUG
16
+ @pool_cv.wait(@pool_mutex)
17
+ end
18
+ end
19
+ @pool << Thread.current
20
+ begin
21
+ yield(*args)
22
+ rescue => e
23
+ on_exception(self, e, *args)
24
+ ensure
25
+ @pool_mutex.synchronize do
26
+ @pool.delete(Thread.current)
27
+ @pool_cv.signal
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ alias_method :new, :run
34
+
35
+ def join
36
+ sleep 0.001 # needed because join must be called after threads
37
+ # had chance to lock
38
+ @pool_mutex.synchronize { @pool_cv.wait(@pool_mutex) until @pool.empty? }
39
+ end
40
+
41
+ def on_exception(thread, exception, *original_args)
42
+ # if you want to handle exception subclass and implement this method
43
+ end
44
+ end
45
+
46
+ class Array
47
+ def peach(size=nil, type=ThreadPool, &block)
48
+ if size == nil
49
+ threads = []
50
+ each { |*args| threads << Thread.new(*args, &block) }
51
+ threads.each {|t| t.join }
52
+ self
53
+ else
54
+ pool = type.new(size)
55
+ each { |*args| pool.new(*args, &block) }
56
+ pool.join
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,34 @@
1
+ require "minitest/autorun"
2
+ require_relative "../lib/thread_pool"
3
+
4
+ describe "ThreadPool" do
5
+ it "should wait for threads to finish" do
6
+ start = Time.now
7
+ 10.times.to_a.peach { sleep 0.1 }
8
+ stop = Time.now
9
+ time = stop - start
10
+ time.must_be :>=, 0.1
11
+ time.must_be :<=, 0.2
12
+ end
13
+
14
+ it "should run at max so many threads" do
15
+ start = Time.now
16
+ 20.times.to_a.peach(10) { sleep(0.1) }
17
+ stop = Time.now
18
+ time = stop - start
19
+ time.must_be :>=, 0.2
20
+ time.must_be :<=, 0.3
21
+ end
22
+
23
+ it "should not stop on long running threads" do
24
+ a = [0.01,0.01,0.2,0.2, 0.01, 0.01,0.01,0.01,0.01,0.01]
25
+ start = Time.now
26
+ a.peach(5) do |time|
27
+ sleep time
28
+ end
29
+ stop = Time.now
30
+ elapsed = stop - start
31
+ elapsed.must_be :>=, 0.2
32
+ elapsed.must_be :<=, 0.3
33
+ end
34
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_thread_pool
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jürgen Bickert
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-17 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: You can easily run number limited threads in parallel with ruby.
15
+ email: juergenbickert@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/thread_pool.rb
21
+ - spec/thread_pool_test.rb
22
+ homepage: http://juergenbickert.de
23
+ licenses: []
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 1.8.15
44
+ signing_key:
45
+ specification_version: 3
46
+ summary: A thread pool library for ruby.
47
+ test_files:
48
+ - spec/thread_pool_test.rb