concur 0.1.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- @thread_pool.process(f)
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
- 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
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
- @mutex.synchronize do # do we even need to synchronize? run should only ever be called once
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.1.2
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: 2011-11-28 00:00:00.000000000 Z
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: &11253020 !ruby/object:Gem::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: *11253020
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: em-http-request
60
- requirement: &11074580 !ruby/object:Gem::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: *11074580
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.markdown
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.markdown
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.11
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