the_force 0.0.3 → 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.
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