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.
@@ -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