concur 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -1 +1 @@
1
- # Concur - A concurrency library for Ruby like java.util.concurrency
1
+ # Concur - A concurrency library for Ruby inspired by java.util.concurrency
data/lib/executor.rb CHANGED
@@ -19,31 +19,55 @@ module Concur
19
19
 
20
20
  end
21
21
 
22
- def self.new_thread_pool_executor(options={})
22
+ def self.new_single_threaded_executor(options={})
23
23
  executor = Executor.new
24
- executor.thread_pool = ThreadPool.new(options[:max_size])
25
- p executor.thread_pool
24
+ executor.thread_pool = SingleThreaded.new
26
25
  executor
27
26
  end
28
27
 
29
- def execute(runnable, &blk)
30
- puts 'executing ' + runnable.inspect
28
+ def self.new_multi_threaded_executor(options={})
29
+ executor = Executor.new
30
+ executor.thread_pool = MultiThreaded.new
31
+ executor
32
+ end
33
+
34
+ def self.new_thread_pool_executor(max_size, options={})
35
+ executor = Executor.new
36
+ executor.thread_pool = ThreadPool.new(max_size)
37
+ executor
38
+ end
39
+
40
+ def execute(runnable=nil, &blk)
31
41
  f = Future.new(runnable, &blk)
32
- if @thread_pool
33
- @thread_pool.process(f)
34
- else
35
- @thread = Thread.new do
36
- f.thread = @thread
37
- f.call
38
- end
39
- end
42
+ @thread_pool.process(f)
40
43
  f
41
44
  end
42
45
 
43
46
  def shutdown
44
- if @thread_pool
45
- @thread_pool.shutdown
46
- end
47
+ @thread_pool.shutdown
48
+ end
49
+ end
50
+
51
+ # todo: should maybe have these backends extend Executor and just override what's necessary
52
+ class SingleThreaded
53
+ def process(f)
54
+ f.call
55
+ end
56
+
57
+ def shutdown
58
+ end
59
+ end
60
+
61
+ class MultiThreaded
62
+ def process(f)
63
+ @thread = Thread.new do
64
+ f.thread = @thread
65
+ f.call
66
+ end
67
+ end
68
+
69
+ def shutdown
70
+
47
71
  end
48
72
  end
49
73
  end
data/lib/future.rb CHANGED
@@ -3,20 +3,10 @@ module Concur
3
3
  #An Future is a class that captures the results of a threaded object so you can retreive the results later.
4
4
  #This is what is returned from Executors.
5
5
  class Future
6
- attr_accessor :thread, :pool
6
+ attr_accessor :thread
7
7
 
8
8
  def initialize(runnable=nil, &block)
9
9
 
10
- # if block
11
- # @thread = Thread.new do
12
- # @result = yield
13
- # end
14
- # else
15
- # @thread = Thread.new do
16
- # @result = runnable.run
17
- # end
18
- # end
19
-
20
10
  @mutex = Mutex.new
21
11
  @cv = ConditionVariable.new
22
12
  @callable = runnable
@@ -27,15 +17,25 @@ module Concur
27
17
  end
28
18
 
29
19
  def run
30
- @result = @callable.call
31
- @complete = true
32
- @cv.signal
20
+ begin
21
+ @result = @callable.call
22
+ rescue Exception => ex
23
+ @ex = ex
24
+ end
25
+ @mutex.synchronize do # do we even need to synchronize? run should only ever be called once
26
+ @complete = true
27
+ @cv.broadcast
28
+ end
33
29
  end
34
30
 
35
31
  def call
36
32
  run
37
33
  end
38
34
 
35
+ def complete?
36
+ @complete
37
+ end
38
+
39
39
  # Returns results. Will wait for thread to complete execution if not already complete.
40
40
  def get
41
41
  # @thread.value
@@ -44,6 +44,9 @@ module Concur
44
44
  @cv.wait(@mutex)
45
45
  end
46
46
  end
47
+ if @ex
48
+ raise @ex
49
+ end
47
50
  @result
48
51
  end
49
52
  end
data/lib/thread_pool.rb CHANGED
@@ -37,12 +37,11 @@ module Concur
37
37
  while @running
38
38
  f = @queue.pop
39
39
  f.thread = t
40
- f.pool = self
41
40
  f.call
42
41
  end
43
- Concur.logger.info "Thread dying " + t.inspect
42
+ # Concur.logger.info "Thread dying " + t.inspect
44
43
  end
45
- Concur.logger.info "Created new thread " + t.inspect
44
+ Concur.logger.debug "Created new thread " + t.inspect
46
45
  @threads << t
47
46
  end
48
47
  end
@@ -6,11 +6,12 @@ require_relative 'job'
6
6
  describe Concur::Executor do
7
7
  describe "#score" do
8
8
  it "runs faster in parallel" do
9
+ times = 10
9
10
 
10
11
  job = Job.new(1)
11
12
  puts 'runnable? ' + job.is_a?(Concur::Runnable).to_s
12
13
  start_time = Time.now
13
- 20.times do |i|
14
+ times.times do |i|
14
15
  job = Job.new(i)
15
16
  job.run
16
17
  end
@@ -20,14 +21,13 @@ describe Concur::Executor do
20
21
  puts '---------------'
21
22
 
22
23
  puts "Now for concurrent"
23
- executor = Concur::Executor.new # unbounded
24
+ executor = Concur::Executor.new_multi_threaded_executor
24
25
  start_time = Time.now
25
26
 
26
27
  jobs = []
27
- 20.times do |i|
28
+ times.times do |i|
28
29
  job = Job.new(i)
29
- future = executor.execute(job)
30
- jobs << future
30
+ jobs << executor.execute(job)
31
31
  end
32
32
  jobs.each do |j|
33
33
  puts "uber fast result=#{j.get}"
@@ -38,11 +38,11 @@ describe Concur::Executor do
38
38
  concurrent_duration.should be < (non_concurrent_duration/2)
39
39
 
40
40
  puts "Now for pooled"
41
- executor = Concur::Executor.new_thread_pool_executor(:max_size=>10)
41
+ executor = Concur::Executor.new_thread_pool_executor(10)
42
42
  start_time = Time.now
43
43
 
44
44
  jobs = []
45
- 20.times do |i|
45
+ times.times do |i|
46
46
  job = Job.new(i)
47
47
  future = executor.execute(job)
48
48
  jobs << future
data/test/job.rb CHANGED
@@ -8,7 +8,7 @@ class Job
8
8
  end
9
9
 
10
10
  def run
11
- sleep 0.25
11
+ sleep 3
12
12
  puts "Finished #{@i}"
13
13
  "response #{@i}"
14
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: concur
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -14,7 +14,7 @@ default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
17
- requirement: &22290888 !ruby/object:Gem::Requirement
17
+ requirement: &25999668 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,8 +22,9 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *22290888
26
- description: A concurrency library for Ruby like java.util.concurrency By http://www.appoxy.com
25
+ version_requirements: *25999668
26
+ description: A concurrency library for Ruby inspired by java.util.concurrency. By
27
+ http://www.appoxy.com
27
28
  email: travis@appoxy.com
28
29
  executables: []
29
30
  extensions: []
@@ -59,10 +60,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
60
  version: '0'
60
61
  requirements: []
61
62
  rubyforge_project:
62
- rubygems_version: 1.6.0
63
+ rubygems_version: 1.6.2
63
64
  signing_key:
64
65
  specification_version: 3
65
- summary: A concurrency library for Ruby like java.util.concurrency. By http://www.appoxy.com
66
+ summary: A concurrency library for Ruby inspired by java.util.concurrency. By http://www.appoxy.com
66
67
  test_files:
67
68
  - test/executor_spec.rb
68
69
  - test/job.rb