concur 0.0.4 → 0.0.6

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.
data/README.markdown CHANGED
@@ -1 +1,29 @@
1
- # Concur - A concurrency library for Ruby inspired by java.util.concurrency
1
+ # Concur - A concurrency library for Ruby inspired by java.util.concurrency
2
+
3
+ ## General Usage
4
+
5
+ # Choose which executor you want, there are several to choose from
6
+ executor = Concur::Executor.new_thread_pool_executor(10)
7
+ start_time = Time.now
8
+
9
+ jobs = []
10
+ times.times do |i|
11
+ future = executor.execute do
12
+ puts "hello #{i}"
13
+ "result #{i}"
14
+ end
15
+ jobs << future
16
+ end
17
+ jobs.each do |j|
18
+ puts "uber fast result=#{j.get}"
19
+ end
20
+ pooled_duration = Time.now - start_time
21
+ puts "pooled_duration=" + pooled_duration.to_s
22
+ executor.shutdown
23
+
24
+ ## Futures
25
+
26
+ A Future is what is returned from the execute method. Call `future.get` to get the results of the block
27
+ or the Callable object. If it's not finished, `get` will block until it is. `get` will also raise an Exception
28
+ if an Exception occurred during running.
29
+
data/lib/concur.rb CHANGED
@@ -1,15 +1,15 @@
1
-
2
- require_relative 'executor'
3
-
4
- require 'logger'
5
- module Concur
6
- @@logger = Logger.new(STDOUT)
7
-
8
- def self.logger
9
- @@logger
10
- end
11
- def self.logger=(logger)
12
- @@logger = logger
13
- end
14
-
1
+
2
+ require_relative 'executor'
3
+
4
+ require 'logger'
5
+ module Concur
6
+ @@logger = Logger.new(STDOUT)
7
+
8
+ def self.logger
9
+ @@logger
10
+ end
11
+ def self.logger=(logger)
12
+ @@logger = logger
13
+ end
14
+
15
15
  end
data/lib/executor.rb CHANGED
@@ -1,73 +1,86 @@
1
- require_relative 'runnable'
2
- require_relative 'future'
3
- require_relative 'thread_pool'
4
-
5
-
6
- module Concur
7
-
8
-
9
- # Decouples task submission from how each task is run. An Executor can be backed by a thread pool or some
10
- # other mechanism, but how you use the Executor won't change. This allows you to change the backend implementation
11
- # with minor code changes.
12
- #
13
- # Inspired by java.util.concurrent.Executor
14
- class Executor
15
-
16
- attr_accessor :thread_pool
17
-
18
- def initialize(options={})
19
-
20
- end
21
-
22
- def self.new_single_threaded_executor(options={})
23
- executor = Executor.new
24
- executor.thread_pool = SingleThreaded.new
25
- executor
26
- end
27
-
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)
41
- f = Future.new(runnable, &blk)
42
- @thread_pool.process(f)
43
- f
44
- end
45
-
46
- def shutdown
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
-
71
- end
72
- end
73
- end
1
+ require_relative 'runnable'
2
+ require_relative 'future'
3
+ require_relative 'thread_pool'
4
+
5
+
6
+ module Concur
7
+
8
+
9
+ # Decouples task submission from how each task is run. An Executor can be backed by a thread pool or some
10
+ # other mechanism, but how you use the Executor won't change. This allows you to change the backend implementation
11
+ # with minor code changes.
12
+ #
13
+ # Inspired by java.util.concurrent.Executor
14
+ class Executor
15
+
16
+ attr_accessor :thread_pool
17
+
18
+ def initialize(options={})
19
+
20
+ end
21
+
22
+ def self.new_single_threaded_executor(options={})
23
+ executor = Executor.new
24
+ executor.thread_pool = SingleThreaded.new
25
+ executor
26
+ end
27
+
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 self.new_eventmachine_executor()
41
+ require_relative 'executors/event_machine_executor'
42
+ executor = EventMachineExecutor.new()
43
+ executor
44
+ end
45
+
46
+ # NOT WORKING
47
+ def self.new_neverblock_executor(max_size)
48
+ require_relative 'executors/never_block_executor'
49
+ executor = NeverBlockExecutor.new(max_size)
50
+ executor
51
+ end
52
+
53
+ def execute(runnable=nil, &blk)
54
+ f = StandardFuture.new(runnable, &blk)
55
+ @thread_pool.process(f)
56
+ f
57
+ end
58
+
59
+ def shutdown
60
+ @thread_pool.shutdown
61
+ end
62
+ end
63
+
64
+ # todo: should maybe have these backends extend Executor and just override what's necessary
65
+ class SingleThreaded
66
+ def process(f)
67
+ f.call
68
+ end
69
+
70
+ def shutdown
71
+ end
72
+ end
73
+
74
+ class MultiThreaded
75
+ def process(f)
76
+ @thread = Thread.new do
77
+ f.thread = @thread
78
+ f.call
79
+ end
80
+ end
81
+
82
+ def shutdown
83
+
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,34 @@
1
+ require 'eventmachine'
2
+ require_relative '../futures/event_machine_future'
3
+
4
+ module Concur
5
+ class EventMachineExecutor
6
+
7
+
8
+ def initialize
9
+ @futures = []
10
+ @em_thread = Thread.new do
11
+ EventMachine.run do
12
+ puts 'Starting EventMachineExecutor...'
13
+ # @futures.each do |f|
14
+ #
15
+ # end
16
+ end
17
+ puts 'EventMachine loop done'
18
+ end
19
+ end
20
+
21
+ def execute(runnable=nil, &blk)
22
+ f = EventMachineFuture.new(runnable, &blk)
23
+ # @futures = f
24
+ EventMachine.schedule(f)
25
+ f
26
+ end
27
+
28
+ def shutdown
29
+ @em_thread.kill
30
+ puts 'shutdown'
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,27 @@
1
+
2
+ require 'neverblock'
3
+
4
+ # This doesn't work as expected. Not sure how to get it to non block on the IO calls
5
+
6
+ module Concur
7
+ class NeverBlockExecutor
8
+
9
+ def initialize(max_size)
10
+ @fiber_pool = NeverBlock::Pool::FiberPool.new(max_size)
11
+ end
12
+
13
+ def execute(runnable=nil, &blk)
14
+ f = Future.new(runnable, &blk)
15
+ @fiber_pool.spawn do
16
+ puts 'running in spawn'
17
+ f.call
18
+ end
19
+ f
20
+ end
21
+
22
+ def shutdown
23
+
24
+ end
25
+
26
+ end
27
+ end
data/lib/future.rb CHANGED
@@ -1,53 +1,64 @@
1
- module Concur
2
-
3
- #An Future is a class that captures the results of a threaded object so you can retreive the results later.
4
- #This is what is returned from Executors.
5
- class Future
6
- attr_accessor :thread
7
-
8
- def initialize(runnable=nil, &block)
9
-
10
- @mutex = Mutex.new
11
- @cv = ConditionVariable.new
12
- @callable = runnable
13
- if block_given?
14
- @callable = block
15
- end
16
-
17
- end
18
-
19
- def run
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
29
- end
30
-
31
- def call
32
- run
33
- end
34
-
35
- def complete?
36
- @complete
37
- end
38
-
39
- # Returns results. Will wait for thread to complete execution if not already complete.
40
- def get
41
- # @thread.value
42
- @mutex.synchronize do
43
- unless @complete
44
- @cv.wait(@mutex)
45
- end
46
- end
47
- if @ex
48
- raise @ex
49
- end
50
- @result
51
- end
52
- end
53
- end
1
+ #An Future is a class that captures the results of a threaded object so you can retrieve the results later.
2
+ #This is what is returned from Executors.
3
+ #
4
+ # This particular Future can be used for synchronous blocks / runnables / callables that are run in a separate thread.
5
+
6
+ module Concur
7
+
8
+ module Future
9
+ def future?
10
+ true
11
+ end
12
+ end
13
+
14
+ class StandardFuture
15
+ include Future
16
+
17
+ attr_accessor :thread, :ex
18
+
19
+ def initialize(runnable=nil, &block)
20
+
21
+ @mutex = Mutex.new
22
+ @cv = ConditionVariable.new
23
+ @callable = runnable
24
+ if block_given?
25
+ @callable = block
26
+ end
27
+
28
+ end
29
+
30
+ def run
31
+ begin
32
+ @result = @callable.call
33
+ rescue Exception => ex
34
+ @ex = ex
35
+ end
36
+ @mutex.synchronize do # do we even need to synchronize? run should only ever be called once
37
+ @complete = true
38
+ @cv.broadcast
39
+ end
40
+ end
41
+
42
+ def call
43
+ run
44
+ end
45
+
46
+ def complete?
47
+ @complete
48
+ end
49
+
50
+ # Returns results. Will wait for thread to complete execution if not already complete.
51
+ def get
52
+ # @thread.value
53
+ @mutex.synchronize do
54
+ unless @complete
55
+ @cv.wait(@mutex)
56
+ end
57
+ end
58
+ if @ex
59
+ raise @ex
60
+ end
61
+ @result
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,164 @@
1
+ # This future enables a blocking get for a result from EventMachine HTTP request.
2
+
3
+ module Concur
4
+
5
+ class EventMachineError < StandardError
6
+
7
+ def initialize(callbackable)
8
+ super("Error in #{callbackable.class.name}")
9
+ @callbackable = callbackable
10
+
11
+ end
12
+ end
13
+
14
+ class EventMachineFutureCallback
15
+
16
+ def future?
17
+ true
18
+ end
19
+
20
+ attr_accessor :errblk, :callblk
21
+
22
+ def initialize(callbackable, &block)
23
+ puts 'EventMachineFutureCallback.initialize: ' + callbackable.inspect
24
+ @callbackable = callbackable
25
+ if block_given?
26
+ @callblk = block
27
+ end
28
+ end
29
+
30
+ def run
31
+
32
+ # http = @callbackable
33
+ # http.errback {
34
+ # @ex = EventMachineError.new(http)
35
+ # complete
36
+ # }
37
+ # http.callback {
38
+ # if @callback
39
+ # @callback.call(@callbackable)
40
+ # end
41
+ # complete
42
+ # }
43
+
44
+
45
+ end
46
+ def errback &blk
47
+ @errblk = blk
48
+ end
49
+
50
+ def callback &blk
51
+ @callblk = blk
52
+ end
53
+
54
+ def errback2 &blk
55
+ puts 'EventMachineFutureCallback.errback'
56
+ proc = Proc.new do
57
+ puts 'errback proc'
58
+ blk.call(@callbackable)
59
+ end
60
+ puts 'setting errback on ' + @callbackable.inspect
61
+ @callbackable.errback &proc
62
+ puts 'errback set'
63
+ end
64
+
65
+ def callback2 &blk
66
+ puts 'EventMachineFutureCallback.callback'
67
+ proc = Proc.new do
68
+ @result = []
69
+ if @callblk
70
+ @result = @callblk.call(@callbackable)
71
+ end
72
+ blk.call(@result)
73
+ end
74
+ @callbackable.callback &proc
75
+ end
76
+ #
77
+ # def call_callback(response)
78
+ # puts 'call_callback=' + response.inspect
79
+ # return unless callblk
80
+ # callblk.call(response)
81
+ # end
82
+ #
83
+ # def call_errback(response)
84
+ # return unless errblk
85
+ # errblk.call(response)
86
+ # end
87
+ end
88
+
89
+ class EventMachineFuture
90
+ include Concur::Future
91
+
92
+ attr_accessor :ex,:result
93
+
94
+ def initialize(callable, &block)
95
+
96
+ @mutex = Mutex.new
97
+ @cv = ConditionVariable.new
98
+ @callable = callable
99
+ if block_given?
100
+ @callable = block
101
+ end
102
+ end
103
+
104
+
105
+ def run
106
+ puts 'EMFuture.run'
107
+ p @callable
108
+ begin
109
+ @callbackable = @callable.call
110
+ puts 'done @callable.call ' + @callbackable.inspect
111
+ rescue Exception => ex
112
+ @ex = ex
113
+ end
114
+ if @ex
115
+ complete
116
+ return
117
+ end
118
+
119
+ http = @callbackable
120
+ http.errback2 {
121
+ puts 'completion errback'
122
+ @ex = EventMachineError.new(http)
123
+ complete
124
+ }
125
+ @result = (http.callback2 {|result|
126
+ @result = result
127
+ complete
128
+ })
129
+ puts '@result=' + @result.inspect
130
+
131
+ end
132
+
133
+ def call
134
+ run
135
+ end
136
+
137
+ def complete
138
+ @complete = true
139
+ end
140
+
141
+
142
+ def complete?
143
+ @complete
144
+ end
145
+
146
+ # Returns results. Will wait for thread to complete execution if not already complete.
147
+ def get
148
+ # @thread.value
149
+ while not @complete
150
+ # todo: gotta be a better way
151
+ puts 'sleeping'
152
+ sleep 0.5
153
+ end
154
+ return get_response
155
+ end
156
+
157
+ def get_response
158
+ if @ex
159
+ raise @ex
160
+ end
161
+ @result
162
+ end
163
+ end
164
+ end
data/lib/runnable.rb CHANGED
@@ -1,13 +1,13 @@
1
-
2
- # A mixin for runnable classes.
3
- module Concur
4
- module Runnable
5
- def run
6
- raise "No run method defined in your runable!"
7
- end
8
-
9
- def call
10
- run
11
- end
12
- end
13
- end
1
+
2
+ # A mixin for runnable classes.
3
+ module Concur
4
+ module Runnable
5
+ def run
6
+ raise "No run method defined in your runable!"
7
+ end
8
+
9
+ def call
10
+ run
11
+ end
12
+ end
13
+ end
data/lib/thread_pool.rb CHANGED
@@ -1,62 +1,62 @@
1
- require 'thread'
2
- begin
3
- require 'fastthread'
4
- rescue LoadError
5
- $stderr.puts "Using the ruby-core thread implementation"
6
- end
7
-
8
- module Concur
9
-
10
- # Another example is here: # from: http://stackoverflow.com/questions/81788/deadlock-in-threadpool
11
- class ThreadPool
12
- def initialize(max_size)
13
- @max_size = max_size
14
- # @thread_queue = SizedQueue.new(max_size)
15
- @running = true
16
- @mutex = Mutex.new
17
- @cv = ConditionVariable.new
18
- @queue = Queue.new
19
- @threads = []
20
-
21
- end
22
-
23
- def shutdown
24
- @running = false
25
- end
26
-
27
- def process(callable, &blk)
28
- callable = blk if block_given?
29
- @queue.push(callable)
30
- start_thread
31
- end
32
-
33
- def start_thread
34
- @mutex.synchronize do
35
- if !@queue.empty? && @threads.size <= @max_size
36
- t = UberThread.new do
37
- while @running
38
- f = @queue.pop
39
- f.thread = t
40
- f.call
41
- end
42
- # Concur.logger.info "Thread dying " + t.inspect
43
- end
44
- Concur.logger.debug "Created new thread " + t.inspect
45
- @threads << t
46
- end
47
- end
48
- end
49
-
50
- class UberThread < Thread
51
-
52
- def initialize
53
- super
54
- end
55
-
56
- end
57
-
58
- end
59
-
60
-
61
-
62
- end
1
+ require 'thread'
2
+ begin
3
+ require 'fastthread'
4
+ rescue LoadError
5
+ $stderr.puts "Using the ruby-core thread implementation"
6
+ end
7
+
8
+ module Concur
9
+
10
+ # Another example is here: # from: http://stackoverflow.com/questions/81788/deadlock-in-threadpool
11
+ class ThreadPool
12
+ def initialize(max_size)
13
+ @max_size = max_size
14
+ # @thread_queue = SizedQueue.new(max_size)
15
+ @running = true
16
+ @mutex = Mutex.new
17
+ @cv = ConditionVariable.new
18
+ @queue = Queue.new
19
+ @threads = []
20
+
21
+ end
22
+
23
+ def shutdown
24
+ @running = false
25
+ end
26
+
27
+ def process(callable, &blk)
28
+ callable = blk if block_given?
29
+ @queue.push(callable)
30
+ start_thread
31
+ end
32
+
33
+ def start_thread
34
+ @mutex.synchronize do
35
+ if !@queue.empty? && @threads.size <= @max_size
36
+ t = UberThread.new do
37
+ while @running
38
+ f = @queue.pop
39
+ f.thread = t
40
+ f.call
41
+ end
42
+ # Concur.logger.info "Thread dying " + t.inspect
43
+ end
44
+ Concur.logger.debug "Created new thread " + t.inspect
45
+ @threads << t
46
+ end
47
+ end
48
+ end
49
+
50
+ class UberThread < Thread
51
+
52
+ def initialize
53
+ super
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+
60
+
61
+
62
+ end
@@ -1,82 +1,87 @@
1
- require 'rspec'
2
-
3
- require_relative '../lib/concur'
4
- require_relative 'job'
5
-
6
- describe Concur::Executor do
7
- describe "#score" do
8
- it "runs faster in parallel" do
9
- times = 10
10
-
11
- job = Job.new(1)
12
- puts 'runnable? ' + job.is_a?(Concur::Runnable).to_s
13
- start_time = Time.now
14
- times.times do |i|
15
- job = Job.new(i)
16
- job.run
17
- end
18
- non_concurrent_duration = Time.now - start_time
19
- puts "duration=" + non_concurrent_duration.to_s
20
-
21
- puts '---------------'
22
-
23
- puts "Now for concurrent"
24
- executor = Concur::Executor.new_multi_threaded_executor
25
- start_time = Time.now
26
-
27
- jobs = []
28
- times.times do |i|
29
- job = Job.new(i)
30
- jobs << executor.execute(job)
31
- end
32
- jobs.each do |j|
33
- puts "uber fast result=#{j.get}"
34
- end
35
- concurrent_duration = Time.now - start_time
36
- puts "duration=" + concurrent_duration.to_s
37
-
38
- concurrent_duration.should be < (non_concurrent_duration/2)
39
-
40
- puts "Now for pooled"
41
- executor = Concur::Executor.new_thread_pool_executor(10)
42
- start_time = Time.now
43
-
44
- jobs = []
45
- times.times do |i|
46
- job = Job.new(i)
47
- future = executor.execute(job)
48
- jobs << future
49
- end
50
- jobs.each do |j|
51
- puts "uber fast result=#{j.get}"
52
- end
53
- pooled_duration = Time.now - start_time
54
- puts "pooled_duration=" + pooled_duration.to_s
55
-
56
- pooled_duration.should be < (non_concurrent_duration/2)
57
- # pooled_duration.should_be > concurrent_duration
58
-
59
- executor.shutdown
60
-
61
- end
62
- end
63
- end
64
-
65
- describe Concur::Future do
66
-
67
- describe "#new" do
68
-
69
- it "can accept blocks" do
70
- future = Concur::Future.new do
71
- puts "i'm in the block"
72
- "result of block"
73
- end
74
- puts 'get=' + future.get
75
- future.get.should == "result of block"
76
- end
77
-
78
- end
79
-
80
- end
81
-
82
-
1
+ require 'rspec'
2
+ require 'neverblock'
3
+
4
+ require_relative '../lib/concur'
5
+ require_relative 'job'
6
+
7
+ @@durations = []
8
+
9
+ def run_jobs(name, executor, times, options={})
10
+ puts "Running #{name}..."
11
+ start_time = Time.now
12
+
13
+ jobs = []
14
+ times.times do |i|
15
+ job = Job.new(i, options)
16
+ jobs << executor.execute(job)
17
+ end
18
+ jobs.each do |j|
19
+ puts "result=#{j.get}"
20
+ end
21
+ concurrent_duration = Time.now - start_time
22
+ o = "#{name} duration=" + concurrent_duration.to_s
23
+ puts o
24
+ @@durations << o
25
+ concurrent_duration
26
+ end
27
+
28
+ describe Concur::Executor do
29
+ describe "#score" do
30
+ it "runs faster in parallel" do
31
+ times = 10
32
+
33
+ job = Job.new(1)
34
+ puts 'runnable? ' + job.is_a?(Concur::Runnable).to_s
35
+ non_concurrent_duration = 0
36
+ #
37
+ executor = Concur::Executor.new_single_threaded_executor
38
+ non_concurrent_duration =run_jobs("non concurrent", executor, times)
39
+ executor.shutdown
40
+
41
+ executor = Concur::Executor.new_multi_threaded_executor
42
+ concurrent_duration = run_jobs("multi thread", executor, times)
43
+ concurrent_duration.should be < (non_concurrent_duration/2)
44
+ executor.shutdown
45
+
46
+ executor = Concur::Executor.new_thread_pool_executor(10)
47
+ pooled_duration = run_jobs("thread pool", executor, times)
48
+ pooled_duration.should be < (non_concurrent_duration/2)
49
+ executor.shutdown
50
+
51
+ # Don't think I know how to use NeverBlock properly
52
+ # executor = Concur::Executor.new_neverblock_executor(10)
53
+ # neverblock_duration = run_jobs("never blocked", executor, times)
54
+ # neverblock_duration.should be < (non_concurrent_duration/2)
55
+ # executor.shutdown
56
+
57
+ executor = Concur::Executor.new_eventmachine_executor()
58
+ em_duration = run_jobs("eventmachine", executor, times, :em=>true)
59
+ em_duration.should be < (non_concurrent_duration/2)
60
+ executor.shutdown
61
+
62
+ @@durations.each do |s|
63
+ puts s
64
+ end
65
+
66
+ end
67
+ end
68
+ end
69
+
70
+ describe Concur::Future do
71
+
72
+ describe "#new" do
73
+
74
+ it "can accept blocks" do
75
+ future = Concur::Future.new do
76
+ puts "i'm in the block"
77
+ "result of block"
78
+ end
79
+ puts 'get=' + future.get
80
+ future.get.should == "result of block"
81
+ end
82
+
83
+ end
84
+
85
+ end
86
+
87
+
data/test/job.rb CHANGED
@@ -1,16 +1,51 @@
1
- require_relative '../lib/runnable'
2
-
3
- class Job
4
- include Concur::Runnable
5
-
6
- def initialize(i)
7
- @i = i
8
- end
9
-
10
- def run
11
- sleep 3
12
- puts "Finished #{@i}"
13
- "response #{@i}"
14
- end
15
-
1
+ require_relative '../lib/runnable'
2
+ require 'rest-client'
3
+ require 'eventmachine'
4
+
5
+ class Job
6
+ include Concur::Runnable
7
+
8
+ def initialize(i, options={})
9
+ @i = i
10
+ if options[:em]
11
+ @em = true
12
+ end
13
+ end
14
+
15
+ def em_request(url)
16
+ puts 'emrequest for ' + url
17
+ http = EventMachine::Protocols::HttpClient.request(
18
+ :host => url,
19
+ :port => 80,
20
+ :request => "/"
21
+ )
22
+ http.callback { |response|
23
+ puts response[:status]
24
+ puts response[:headers]
25
+ puts response[:content]
26
+ }
27
+ end
28
+
29
+ def run
30
+ puts "Starting #{@i}... em? #{@em}"
31
+ # sleep 1
32
+ urls = ["www.yahoo.com", "www.microsoft.com"] # , "www.github.com"
33
+ if @em
34
+ urls.each do |u|
35
+ em_request(u)
36
+ end
37
+ else
38
+ urls.each do |u|
39
+ get(u)
40
+ end
41
+ end
42
+ puts "Finished #{@i}"
43
+ "response #{@i}"
44
+ end
45
+
46
+ def get(url)
47
+ puts 'getting ' + url
48
+ RestClient.get "http://#{url}"
49
+ end
50
+
16
51
  end
metadata CHANGED
@@ -1,69 +1,65 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: concur
3
- version: !ruby/object:Gem::Version
4
- version: 0.0.4
3
+ version: !ruby/object:Gem::Version
5
4
  prerelease:
5
+ version: 0.0.6
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Travis Reeder
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-03-10 00:00:00.000000000 -08:00
13
- default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: rspec
17
- requirement: &25999668 !ruby/object:Gem::Requirement
18
- none: false
19
- requirements:
20
- - - ! '>='
21
- - !ruby/object:Gem::Version
22
- version: '0'
23
- type: :runtime
24
- prerelease: false
25
- version_requirements: *25999668
26
- description: A concurrency library for Ruby inspired by java.util.concurrency. By
27
- http://www.appoxy.com
12
+
13
+ date: 2011-05-02 00:00:00 Z
14
+ dependencies: []
15
+
16
+ description: A concurrency library for Ruby inspired by java.util.concurrency. By http://www.appoxy.com
28
17
  email: travis@appoxy.com
29
18
  executables: []
19
+
30
20
  extensions: []
31
- extra_rdoc_files:
21
+
22
+ extra_rdoc_files:
32
23
  - README.markdown
33
- files:
24
+ files:
34
25
  - lib/concur.rb
35
26
  - lib/executor.rb
27
+ - lib/executors/event_machine_executor.rb
28
+ - lib/executors/never_block_executor.rb
36
29
  - lib/future.rb
30
+ - lib/futures/event_machine_future.rb
37
31
  - lib/runnable.rb
38
32
  - lib/thread_pool.rb
39
33
  - README.markdown
40
34
  - test/executor_spec.rb
41
35
  - test/job.rb
42
- has_rdoc: true
43
36
  homepage: http://github.com/appoxy/concur/
44
37
  licenses: []
38
+
45
39
  post_install_message:
46
40
  rdoc_options: []
47
- require_paths:
41
+
42
+ require_paths:
48
43
  - lib
49
- required_ruby_version: !ruby/object:Gem::Requirement
44
+ required_ruby_version: !ruby/object:Gem::Requirement
50
45
  none: false
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
51
  none: false
57
- requirements:
58
- - - ! '>='
59
- - !ruby/object:Gem::Version
60
- version: '0'
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
61
56
  requirements: []
57
+
62
58
  rubyforge_project:
63
- rubygems_version: 1.6.2
59
+ rubygems_version: 1.7.2
64
60
  signing_key:
65
61
  specification_version: 3
66
62
  summary: A concurrency library for Ruby inspired by java.util.concurrency. By http://www.appoxy.com
67
- test_files:
63
+ test_files:
68
64
  - test/executor_spec.rb
69
65
  - test/job.rb