concur 0.1.2 → 1.0.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.
- data/{README.markdown → README.md} +38 -0
- data/lib/concur/config.rb +36 -0
- data/lib/concur/go.rb +57 -0
- data/lib/concur.rb +7 -1
- data/lib/executor.rb +23 -23
- data/lib/future.rb +7 -8
- data/lib/thread_pool.rb +9 -2
- metadata +12 -44
@@ -1,5 +1,41 @@
|
|
1
1
|
# Concur - A concurrency library for Ruby inspired by java.util.concurrency
|
2
2
|
|
3
|
+
## NEW Go Style Usage
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
require 'concur/go'
|
7
|
+
|
8
|
+
# set max threads (optional)
|
9
|
+
Concur.config.max_threads = 10
|
10
|
+
|
11
|
+
# fire off blocks using go
|
12
|
+
1.times do |i|
|
13
|
+
go do
|
14
|
+
puts "hello #{i}"
|
15
|
+
sleep 2
|
16
|
+
puts "#{i} awoke"
|
17
|
+
puts "hhi there"
|
18
|
+
end
|
19
|
+
puts "done #{i}"
|
20
|
+
end
|
21
|
+
|
22
|
+
# Use channels to communicate
|
23
|
+
ch = Concur::Channel.new
|
24
|
+
20.times do |i|
|
25
|
+
go(ch) do |ch|
|
26
|
+
puts "hello channel #{i} #{ch}"
|
27
|
+
sleep 2
|
28
|
+
# push to channel
|
29
|
+
ch << "pushed #{i} to channel"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Read from channel
|
34
|
+
ch.each do |x|
|
35
|
+
puts "Got #{x} from channel"
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
3
39
|
## General Usage
|
4
40
|
|
5
41
|
# Choose which executor you want, there are several to choose from
|
@@ -23,6 +59,8 @@
|
|
23
59
|
|
24
60
|
## EventMachine / Non-blocking I/O
|
25
61
|
|
62
|
+
DEPRECATED!!
|
63
|
+
|
26
64
|
Perhaps more important/interesting these days is EventMachine/non-blocking io. When your program is io bound you can
|
27
65
|
get similar performance (if not better) on a single thread as you can with multi-threads.
|
28
66
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Concur
|
2
|
+
class Config
|
3
|
+
attr_reader :defaults
|
4
|
+
|
5
|
+
def initialize(options={})
|
6
|
+
init_defaults
|
7
|
+
@listeners = []
|
8
|
+
@max_threads = options[:max_threads] || defaults[:max_threads]
|
9
|
+
end
|
10
|
+
|
11
|
+
def init_defaults
|
12
|
+
@defaults = {
|
13
|
+
max_threads: 20
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def max_threads=(x)
|
18
|
+
@max_threads = x
|
19
|
+
notify_listeners(:max_threads=>x)
|
20
|
+
end
|
21
|
+
|
22
|
+
def max_threads
|
23
|
+
@max_threads
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_listener(l)
|
27
|
+
@listeners << l
|
28
|
+
end
|
29
|
+
|
30
|
+
def notify_listeners(changes)
|
31
|
+
@listeners.each do |l|
|
32
|
+
l.update(changes)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/concur/go.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Kernel
|
2
|
+
def go(ch=nil, &blk)
|
3
|
+
future = Concur.gok.executor.execute(nil, ch, &blk)
|
4
|
+
future
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
module Concur
|
9
|
+
class GoKernel
|
10
|
+
def initialize(config)
|
11
|
+
@config = config
|
12
|
+
@executor = Concur::Executor.new_thread_pool_executor(@config.max_threads)
|
13
|
+
@config.add_listener(@executor)
|
14
|
+
end
|
15
|
+
|
16
|
+
def executor
|
17
|
+
@executor
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
@gok = GoKernel.new(Concur.config)
|
22
|
+
|
23
|
+
def self.gok
|
24
|
+
@gok
|
25
|
+
end
|
26
|
+
|
27
|
+
class Channel
|
28
|
+
def initialize
|
29
|
+
@queue = Queue.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def <<(ob)
|
33
|
+
@queue << ob
|
34
|
+
end
|
35
|
+
|
36
|
+
def shift
|
37
|
+
begin
|
38
|
+
@queue.shift
|
39
|
+
rescue Exception => ex
|
40
|
+
#puts ex.class.name
|
41
|
+
#p ex
|
42
|
+
#p ex.message
|
43
|
+
if ex.class.name == "fatal" && ex.message.include?("deadlock")
|
44
|
+
return nil
|
45
|
+
end
|
46
|
+
raise ex
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def each(&blk)
|
51
|
+
while (x = shift) do
|
52
|
+
yield x
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
data/lib/concur.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
require 'logger'
|
1
2
|
|
3
|
+
require_relative 'concur/config'
|
2
4
|
require_relative 'executor'
|
3
5
|
require_relative 'thread_pool'
|
4
6
|
|
5
|
-
require 'logger'
|
6
7
|
module Concur
|
7
8
|
@@logger = Logger.new(STDOUT)
|
9
|
+
@@config = Config.new
|
8
10
|
|
9
11
|
def self.logger
|
10
12
|
@@logger
|
@@ -13,4 +15,8 @@ module Concur
|
|
13
15
|
@@logger = logger
|
14
16
|
end
|
15
17
|
|
18
|
+
def self.config
|
19
|
+
@@config ||= Config.new
|
20
|
+
end
|
21
|
+
|
16
22
|
end
|
data/lib/executor.rb
CHANGED
@@ -26,7 +26,7 @@ module Concur
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def http_request(params, &blk)
|
29
|
-
|
29
|
+
puts 'http_request is deprecated'
|
30
30
|
f = StandardFuture.new do
|
31
31
|
conn = Faraday.new(:url => params[:base_url]) do |builder|
|
32
32
|
# builder.use Faraday::Request::UrlEncoded # convert request params as "www-form-urlencoded"
|
@@ -50,7 +50,7 @@ module Concur
|
|
50
50
|
end
|
51
51
|
response
|
52
52
|
end
|
53
|
-
|
53
|
+
process(f)
|
54
54
|
f
|
55
55
|
end
|
56
56
|
|
@@ -78,19 +78,19 @@ module Concur
|
|
78
78
|
executor = ThreadPool.new(max_size)
|
79
79
|
executor
|
80
80
|
end
|
81
|
-
|
82
|
-
def self.new_eventmachine_executor()
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
end
|
87
|
-
|
88
|
-
|
89
|
-
def self.new_neverblock_executor(max_size)
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end
|
81
|
+
#
|
82
|
+
#def self.new_eventmachine_executor()
|
83
|
+
# require_relative 'executors/event_machine_executor'
|
84
|
+
# executor = EventMachineExecutor.new()
|
85
|
+
# executor
|
86
|
+
#end
|
87
|
+
#
|
88
|
+
## NOT WORKING
|
89
|
+
#def self.new_neverblock_executor(max_size)
|
90
|
+
# require_relative 'executors/never_block_executor'
|
91
|
+
# executor = NeverBlockExecutor.new(max_size)
|
92
|
+
# executor
|
93
|
+
#end
|
94
94
|
|
95
95
|
|
96
96
|
end
|
@@ -98,14 +98,14 @@ module Concur
|
|
98
98
|
|
99
99
|
# todo: should maybe have these backends extend Executor and just override what's necessary
|
100
100
|
class SingleThreaded < Executor::Base
|
101
|
-
def process(f=nil, &blk)
|
102
|
-
f = StandardFuture.new(f, &blk)
|
101
|
+
def process(f=nil, channel=nil, &blk)
|
102
|
+
f = StandardFuture.new(f, channel, &blk)
|
103
103
|
f.call
|
104
104
|
f
|
105
105
|
end
|
106
106
|
|
107
|
-
def execute(f=nil, &blk)
|
108
|
-
process(f, &blk)
|
107
|
+
def execute(f=nil, channel=nil, &blk)
|
108
|
+
process(f, channel, &blk)
|
109
109
|
end
|
110
110
|
|
111
111
|
def shutdown
|
@@ -114,8 +114,8 @@ module Concur
|
|
114
114
|
|
115
115
|
# Spins off a new thread per job
|
116
116
|
class MultiThreaded < Executor::Base
|
117
|
-
def process(f=nil, &blk)
|
118
|
-
f = StandardFuture.new(f, &blk)
|
117
|
+
def process(f=nil, channel=nil, &blk)
|
118
|
+
f = StandardFuture.new(f, channel, &blk)
|
119
119
|
@thread = Thread.new do
|
120
120
|
f.call
|
121
121
|
end
|
@@ -123,8 +123,8 @@ module Concur
|
|
123
123
|
f
|
124
124
|
end
|
125
125
|
|
126
|
-
def execute(f=nil, &blk)
|
127
|
-
process(f, &blk)
|
126
|
+
def execute(f=nil, channel=nil, &blk)
|
127
|
+
process(f, channel, &blk)
|
128
128
|
end
|
129
129
|
|
130
130
|
def shutdown
|
data/lib/future.rb
CHANGED
@@ -16,34 +16,33 @@ module Concur
|
|
16
16
|
|
17
17
|
attr_accessor :thread, :ex
|
18
18
|
|
19
|
-
def initialize(runnable=nil, &block)
|
19
|
+
def initialize(runnable=nil, channel=nil, &block)
|
20
20
|
|
21
21
|
@mutex = Mutex.new
|
22
22
|
@cv = ConditionVariable.new
|
23
23
|
@callable = runnable
|
24
|
+
@channel = channel
|
24
25
|
if block_given?
|
25
26
|
@callable = block
|
26
27
|
end
|
27
28
|
|
28
29
|
end
|
29
30
|
|
30
|
-
def run
|
31
|
+
def run(channel=nil)
|
31
32
|
#Concur.logger.debug 'running StandardFuture'
|
32
33
|
begin
|
33
|
-
@result = @callable.call
|
34
|
+
@result = @callable.call(@channel)
|
34
35
|
Concur.logger.debug 'callable result: ' + @result.inspect
|
35
36
|
rescue Exception => ex
|
36
|
-
Concur.logger.debug "Error occurred! #{ex.class.name}: #{ex.message}"
|
37
|
+
Concur.logger.debug "Error occurred! #{ex.class.name}: #{ex.message}: " + ex.backtrace.inspect
|
37
38
|
@ex = ex
|
38
39
|
end
|
39
|
-
@
|
40
|
-
@complete = true
|
41
|
-
end
|
40
|
+
@complete = true
|
42
41
|
@cv.broadcast
|
43
42
|
|
44
43
|
end
|
45
44
|
|
46
|
-
def call
|
45
|
+
def call(channel=nil)
|
47
46
|
run
|
48
47
|
end
|
49
48
|
|
data/lib/thread_pool.rb
CHANGED
@@ -27,6 +27,13 @@ module Concur
|
|
27
27
|
@running = false
|
28
28
|
end
|
29
29
|
|
30
|
+
# listen for config changes
|
31
|
+
def update(changes)
|
32
|
+
if changes[:max_threads]
|
33
|
+
@max_size = changes[:max_threads]
|
34
|
+
puts "Changed max size to #{changes[:max_threads]}"
|
35
|
+
end
|
36
|
+
end
|
30
37
|
|
31
38
|
def process(callable, &blk)
|
32
39
|
callable = blk if block_given?
|
@@ -34,8 +41,8 @@ module Concur
|
|
34
41
|
start_thread
|
35
42
|
end
|
36
43
|
|
37
|
-
def execute(runnable=nil, &blk)
|
38
|
-
f = StandardFuture.new(runnable, &blk)
|
44
|
+
def execute(runnable=nil, channel=nil, &blk)
|
45
|
+
f = StandardFuture.new(runnable, channel, &blk)
|
39
46
|
process(f)
|
40
47
|
f
|
41
48
|
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.
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,33 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-07-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: eventmachine
|
16
|
-
requirement: &11255500 !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
22
|
-
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: *11255500
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: em-http-request
|
27
|
-
requirement: &11254080 !ruby/object:Gem::Requirement
|
28
|
-
none: false
|
29
|
-
requirements:
|
30
|
-
- - ! '>='
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '0'
|
33
|
-
type: :runtime
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: *11254080
|
36
14
|
- !ruby/object:Gem::Dependency
|
37
15
|
name: faraday
|
38
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
39
17
|
none: false
|
40
18
|
requirements:
|
41
19
|
- - ! '>='
|
@@ -43,21 +21,15 @@ dependencies:
|
|
43
21
|
version: '0'
|
44
22
|
type: :runtime
|
45
23
|
prerelease: false
|
46
|
-
version_requirements:
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: eventmachine
|
49
|
-
requirement: &11252360 !ruby/object:Gem::Requirement
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
25
|
none: false
|
51
26
|
requirements:
|
52
27
|
- - ! '>='
|
53
28
|
- !ruby/object:Gem::Version
|
54
29
|
version: '0'
|
55
|
-
type: :runtime
|
56
|
-
prerelease: false
|
57
|
-
version_requirements: *11252360
|
58
30
|
- !ruby/object:Gem::Dependency
|
59
|
-
name:
|
60
|
-
requirement:
|
31
|
+
name: faraday
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
61
33
|
none: false
|
62
34
|
requirements:
|
63
35
|
- - ! '>='
|
@@ -65,18 +37,12 @@ dependencies:
|
|
65
37
|
version: '0'
|
66
38
|
type: :runtime
|
67
39
|
prerelease: false
|
68
|
-
version_requirements:
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: faraday
|
71
|
-
requirement: &11669620 !ruby/object:Gem::Requirement
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
72
41
|
none: false
|
73
42
|
requirements:
|
74
43
|
- - ! '>='
|
75
44
|
- !ruby/object:Gem::Version
|
76
45
|
version: '0'
|
77
|
-
type: :runtime
|
78
|
-
prerelease: false
|
79
|
-
version_requirements: *11669620
|
80
46
|
description: A concurrency library for Ruby inspired by java.util.concurrency. By
|
81
47
|
http://www.appoxy.com
|
82
48
|
email: travis@appoxy.com
|
@@ -84,10 +50,12 @@ executables: []
|
|
84
50
|
extensions: []
|
85
51
|
extra_rdoc_files:
|
86
52
|
- LICENSE.markdown
|
87
|
-
- README.
|
53
|
+
- README.md
|
88
54
|
files:
|
89
55
|
- lib/completer.rb
|
90
56
|
- lib/concur.rb
|
57
|
+
- lib/concur/config.rb
|
58
|
+
- lib/concur/go.rb
|
91
59
|
- lib/executor.rb
|
92
60
|
- lib/executors/event_machine_executor.rb
|
93
61
|
- lib/executors/never_block_executor.rb
|
@@ -96,7 +64,7 @@ files:
|
|
96
64
|
- lib/runnable.rb
|
97
65
|
- lib/thread_pool.rb
|
98
66
|
- LICENSE.markdown
|
99
|
-
- README.
|
67
|
+
- README.md
|
100
68
|
homepage: http://github.com/appoxy/concur/
|
101
69
|
licenses: []
|
102
70
|
post_install_message:
|
@@ -117,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
85
|
version: '0'
|
118
86
|
requirements: []
|
119
87
|
rubyforge_project:
|
120
|
-
rubygems_version: 1.8.
|
88
|
+
rubygems_version: 1.8.24
|
121
89
|
signing_key:
|
122
90
|
specification_version: 3
|
123
91
|
summary: A concurrency library for Ruby inspired by java.util.concurrency. By http://www.appoxy.com
|