the_force 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/Rakefile +1 -1
  2. data/lib/the_force/thread_pool.rb +33 -85
  3. metadata +3 -3
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ exclude_file_globs = []
7
7
 
8
8
  spec = Gem::Specification.new do |s|
9
9
  s.name = "the_force"
10
- s.version = '0.0.3'
10
+ s.version = '0.1.0'
11
11
  s.author = "Ryan Ziegler"
12
12
  s.email = "info@symbolforce.com"
13
13
  s.homepage = "http://www.symbolforce.com"
@@ -7,102 +7,50 @@ end
7
7
 
8
8
  module TheForce
9
9
  class ThreadPool
10
- class Worker
11
- def initialize(thread_queue)
12
- @mutex = Mutex.new
13
- @cv = ConditionVariable.new
14
- @queue = thread_queue
15
- @running = true
16
- @thread = Thread.new do
17
- @mutex.synchronize do
18
- while @running
19
- @cv.wait(@mutex)
20
- block = get_block
21
- if block
22
- @mutex.unlock
23
- block.call
24
- @mutex.lock
25
- reset_block
26
- end
27
- @queue << self
28
- end
29
- end
30
- end
31
- end
32
-
33
- def name
34
- @thread.inspect
35
- end
36
-
37
- def get_block
38
- @block
39
- end
10
+ def initialize(max_size)
11
+ @pool = []
12
+ @max_size = max_size
13
+ @pool_mutex = Mutex.new
14
+ @pool_cv = ConditionVariable.new
15
+ end
40
16
 
41
- def set_block(block)
42
- @mutex.synchronize do
43
- raise RuntimeError, "Thread already busy." if @block
44
- @block = block
45
- # Signal the thread in this class, that there's a job to be done
46
- @cv.signal
17
+ def dispatch(*args)
18
+ Thread.new do
19
+ # Wait for space in the pool.
20
+ @pool_mutex.synchronize do
21
+ while @pool.size >= @max_size
22
+ # Sleep until some other thread calls @pool_cv.signal.
23
+ @pool_cv.wait(@pool_mutex)
24
+ end
47
25
  end
48
- end
49
-
50
- def reset_block
51
- @block = nil
52
- end
53
-
54
- def busy?
55
- @mutex.synchronize { !@block.nil? }
56
- end
57
26
 
58
- def stop
59
- @mutex.synchronize do
60
- @running = false
61
- @cv.signal
27
+ @pool << Thread.current
28
+ begin
29
+ yield(*args)
30
+ rescue => e
31
+ exception(self, e, *args)
32
+ ensure
33
+ @pool_mutex.synchronize do
34
+ # Remove the thread from the pool.
35
+ @pool.delete(Thread.current)
36
+ # Signal the next waiting thread that there's a space in the pool.
37
+ @pool_cv.signal
38
+ end
62
39
  end
63
- @thread.join
64
40
  end
65
41
  end
66
42
 
67
- attr_accessor :max_size
68
-
69
- def initialize(max_size = 10)
70
- @max_size = max_size
71
- @queue = Queue.new
72
- @workers = []
73
- end
74
-
75
- def size
76
- @workers.size
77
- end
78
-
79
- def busy?
80
- @queue.size < @workers.size
81
- end
82
-
83
43
  def shutdown
84
- @workers.each { |w| w.stop }
85
- @workers = []
44
+ @pool_mutex.synchronize { @pool_cv.wait(@pool_mutex) until @pool.empty? }
86
45
  end
87
46
 
88
- alias :join :shutdown
89
-
90
- def process(block=nil,&blk)
91
- block = blk if block_given?
92
- worker = get_worker
93
- worker.set_block(block)
47
+ def busy?
48
+ @pool.length > 0
94
49
  end
95
50
 
96
- private
97
-
98
- def get_worker
99
- if !@queue.empty? or @workers.size == @max_size
100
- return @queue.pop
101
- else
102
- worker = Worker.new(@queue)
103
- @workers << worker
104
- worker
105
- end
106
- end
51
+ def exception(thread, exception, *original_args)
52
+ # Subclass this method to handle an exception within a thread.
53
+ puts "Exception in thread #{thread}: #{exception}"
54
+ end
107
55
  end
108
56
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: the_force
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 3
10
- version: 0.0.3
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ryan Ziegler