opee 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -24,9 +24,9 @@ Give it a try. Any comments, thoughts, or suggestions are welcome.
24
24
 
25
25
  ## <a name="release">Release Notes</a>
26
26
 
27
- ### Release 1.0.1
27
+ ### Release 1.0.2
28
28
 
29
- - Fixed bug in Exception handling
29
+ - Added AskQueue which serves up method invocations instead of jobs.
30
30
 
31
31
  # Plans and Notes
32
32
 
@@ -6,6 +6,8 @@ require 'opee/errors'
6
6
  require 'opee/env'
7
7
  require 'opee/actor'
8
8
  require 'opee/log'
9
+ require 'opee/queue'
9
10
  require 'opee/workqueue'
11
+ require 'opee/askqueue'
10
12
  require 'opee/job'
11
13
  require 'opee/collector'
@@ -158,7 +158,7 @@ module Opee
158
158
  # @param [Array] args arguments to the op method
159
159
  # @param [Proc] blk ignored
160
160
  def method_missing(m, *args, &blk)
161
- raise NoMethodError.new("undefine method '#{m}' for #{self.class}", m, args) unless respond_to?(m, true)
161
+ raise NoMethodError.new("undefined method '#{m}' for #{self.class}", m, args) unless respond_to?(m, true)
162
162
  ask(m, *args)
163
163
  end
164
164
 
@@ -0,0 +1,29 @@
1
+
2
+ module Opee
3
+ # Implements a work queue Actor that will distribute method calls to Actors
4
+ # that volunteer to execute those methods. The primary use is to distribute
5
+ # work across multiple workers.
6
+ class AskQueue < Queue
7
+
8
+ def initialize(options={})
9
+ super(options)
10
+ end
11
+
12
+ # Queues an operation and arguments to be handed off to a worker when the worker is ready.
13
+ # @param [Symbol] op method to queue for the Actor
14
+ # @param [Array] args arguments to the op method
15
+ # @raise [BusyError] if the request queue does not become available in the {#ask_timeout} seconds
16
+ def add_method(op, *args)
17
+ ask(:add, Act.new(op, args))
18
+ end
19
+
20
+ private
21
+
22
+ # Asks the worker to invoke the method of an Act Object.
23
+ def ask_worker(worker, job)
24
+ raise NoMethodError.new("undefined method for #{job.class}. Expected a method invocation") unless job.is_a?(Actor::Act)
25
+ worker.ask(job.op, *job.args)
26
+ end
27
+
28
+ end # AskQueue
29
+ end # Opee
@@ -120,7 +120,6 @@ module Opee
120
120
  # rescue() method is called.
121
121
  # @param [Exception] ex Exception to handle
122
122
  def self.rescue(ex)
123
- puts "*** rescue"
124
123
  begin
125
124
  log_rescue(ex)
126
125
  @@rescuer.rescue(ex) unless @@rescuer.nil?
@@ -0,0 +1,94 @@
1
+
2
+ module Opee
3
+ # Implements a queue Actor that will distribute jobs to Actors that
4
+ # volunteer to complete those jobs. The primary use is to distribute work or
5
+ # jobs across multiple workers.
6
+ class Queue < Actor
7
+
8
+ def initialize(options={})
9
+ @workers = []
10
+ @work_queue = []
11
+ @max_job_count = 0
12
+ @job_timeout = 3.0
13
+ @add_thread = nil
14
+ super(options)
15
+ end
16
+
17
+ # Returns the number of jobs currently on the work queue.
18
+ # @return [Fixnum] number of waiting jobs
19
+ def work_queue_size()
20
+ @work_queue.size
21
+ end
22
+
23
+ # Returns the number of worker Actors waiting to process jobs.
24
+ # @return [Fixnum] number of waiting workers
25
+ def worker_count()
26
+ @workers.size
27
+ end
28
+
29
+ # Returns the true if any requests are queued, a request is being
30
+ # processed, or if there are jobs waiting on the work request queue.
31
+ # @return [true|false] true if busy, false otherwise
32
+ def busy?
33
+ !@work_queue.empty? || super
34
+ end
35
+
36
+ # Verifies that additional jobs can be added to the work queue before
37
+ # allowing an {#add}() to be called.
38
+ # @see Actor#ask
39
+ def ask(op, *args)
40
+ if :add == op && 0 < @max_job_count && (@work_queue.size() + @queue.size()) >= @max_job_count
41
+ unless 0.0 >= @job_timeout
42
+ @add_thread = Thread.current
43
+ give_up_at = Time.now + @job_timeout
44
+ until Time.now > give_up_at || (@work_queue.size() + @queue.size()) < @max_job_count
45
+ sleep(@job_timeout)
46
+ end
47
+ @add_thread = nil
48
+ end
49
+ raise BusyError.new() unless @work_queue.size() < @max_job_count
50
+ end
51
+ super
52
+ end
53
+
54
+ private
55
+
56
+ # Processes the initialize() options. Subclasses should call super.
57
+ # @param [Hash] options options to be used for initialization
58
+ # @option options [Symbol] :method method to call on workers
59
+ # @option options [Fixnum] :max_job_count maximum number of jobs
60
+ # that can be queued before backpressure is applied to the caller.
61
+ # @option options [Float] :job_timeout timeout in seconds to wait
62
+ # before raising a BusyError if the work queue is too long.
63
+ def set_options(options)
64
+ super(options)
65
+ @max_job_count = options.fetch(:max_job_count, @max_job_count)
66
+ @job_timeout = options.fetch(:job_timeout, @job_timeout)
67
+ end
68
+
69
+ # Places a job on the work queue. This method is executed asynchronously.
70
+ # @param [Object] job work to be processed
71
+ def add(job)
72
+ if @workers.empty?
73
+ @work_queue.insert(0, job)
74
+ else
75
+ worker = @workers.pop()
76
+ ask_worker(worker, job)
77
+ end
78
+ end
79
+
80
+ # Identifies a worker as available to process jobs when they become
81
+ # available. This method is executed asynchronously.
82
+ # @param [Actor] worker Actor that responds to the {#method}
83
+ def ready(worker)
84
+ if @work_queue.empty?
85
+ @workers.insert(0, worker) unless @workers.include?(worker)
86
+ else
87
+ job = @work_queue.pop()
88
+ @add_thread.wakeup() unless @add_thread.nil?
89
+ ask_worker(worker, job)
90
+ end
91
+ end
92
+
93
+ end # Queue
94
+ end # Opee
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Opee
3
3
  # Current version of the module.
4
- VERSION = '1.0.1'
4
+ VERSION = '1.0.2'
5
5
  end
@@ -1,26 +1,15 @@
1
1
 
2
2
  module Opee
3
- # Implements a work queue Actor that ill distribute jobs to Actors that
3
+ # Implements a work queue Actor that will distribute jobs to Actors that
4
4
  # volunteer to complete those jobs. The primary use is to distribute work or
5
5
  # jobs across multiple workers.
6
- class WorkQueue < Actor
6
+ class WorkQueue < Queue
7
7
 
8
8
  def initialize(options={})
9
- @workers = []
10
- @work_queue = []
11
9
  @method = nil
12
- @max_job_count = 0
13
- @job_timeout = 3.0
14
- @add_thread = nil
15
10
  super(options)
16
11
  end
17
12
 
18
- # Returns the number of jobs currently on the work queue.
19
- # @return [Fixnum] number of waiting jobs
20
- def work_queue_size()
21
- @work_queue.size
22
- end
23
-
24
13
  # Returns the number of worker Actors waiting to process jobs.
25
14
  # @return [Fixnum] number of waiting workers
26
15
  def worker_count()
@@ -33,69 +22,19 @@ module Opee
33
22
  @workers.size
34
23
  end
35
24
 
36
- # Returns the true if any requests are queued, a request is being
37
- # processed, or if there are jobs waiting on the work request queue.
38
- # @return [true|false] true if busy, false otherwise
39
- def busy?
40
- !@work_queue.empty? || super
41
- end
42
-
43
- # Verifies that additional jobs can be added to the work queue before
44
- # allowing an {#add}() to be called.
45
- # @see Actor#ask
46
- def ask(op, *args)
47
- if :add == op && 0 < @max_job_count && (@work_queue.size() + @queue.size()) >= @max_job_count
48
- unless 0.0 >= @job_timeout
49
- @add_thread = Thread.current
50
- give_up_at = Time.now + @job_timeout
51
- until Time.now > give_up_at || (@work_queue.size() + @queue.size()) < @max_job_count
52
- sleep(@job_timeout)
53
- end
54
- @add_thread = nil
55
- end
56
- raise BusyError.new() unless @work_queue.size() < @max_job_count
57
- end
58
- super
59
- end
60
-
61
25
  private
62
26
 
63
27
  # Processes the initialize() options. Subclasses should call super.
64
28
  # @param [Hash] options options to be used for initialization
65
29
  # @option options [Symbol] :method method to call on workers
66
- # @option options [Fixnum] :max_job_count maximum number of jobs
67
- # that can be queued before backpressure is applied to the caller.
68
- # @option options [Float] :job_timeout timeout in seconds to wait
69
- # before raising a BusyError if the work queue is too long.
70
30
  def set_options(options)
71
31
  super(options)
72
32
  raise MissingOptionError.new(:method, "for processing jobs") if (@method = options[:method]).nil?
73
- @max_job_count = options.fetch(:max_job_count, @max_job_count)
74
- @job_timeout = options.fetch(:job_timeout, @job_timeout)
75
- end
76
-
77
- # Places a job on the work queue. This method is executed asynchronously.
78
- # @param [Object] job work to be processed
79
- def add(job)
80
- if @workers.empty?
81
- @work_queue.insert(0, job)
82
- else
83
- worker = @workers.pop()
84
- worker.ask(@method, job)
85
- end
86
33
  end
87
34
 
88
- # Identifies a worker as available to process jobs when they become
89
- # available. This method is executed asynchronously.
90
- # @param [Actor] worker Actor that responds to the {#method}
91
- def ready(worker)
92
- if @work_queue.empty?
93
- @workers.insert(0, worker) unless @workers.include?(worker)
94
- else
95
- job = @work_queue.pop()
96
- @add_thread.wakeup() unless @add_thread.nil?
97
- worker.ask(@method, job)
98
- end
35
+ # Asks the worker to invoke the default method on a job.
36
+ def ask_worker(worker, job)
37
+ worker.ask(@method, job)
99
38
  end
100
39
 
101
40
  end # WorkQueue
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opee
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-18 00:00:00.000000000 Z
12
+ date: 2012-05-29 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! 'An experimental Object-base Parallel Evaluation Environment. '
15
15
  email: peter@ohler.com
@@ -19,11 +19,13 @@ extra_rdoc_files:
19
19
  - README.md
20
20
  files:
21
21
  - lib/opee/actor.rb
22
+ - lib/opee/askqueue.rb
22
23
  - lib/opee/collector.rb
23
24
  - lib/opee/env.rb
24
25
  - lib/opee/errors.rb
25
26
  - lib/opee/job.rb
26
27
  - lib/opee/log.rb
28
+ - lib/opee/queue.rb
27
29
  - lib/opee/version.rb
28
30
  - lib/opee/workqueue.rb
29
31
  - lib/opee.rb
@@ -33,7 +35,6 @@ files:
33
35
  - test/tc_opee_env.rb
34
36
  - test/tc_opee_log.rb
35
37
  - test/tc_opee_workqueue.rb
36
- - test/tests.rb
37
38
  - test/ts_opee.rb
38
39
  - LICENSE
39
40
  - README.md
@@ -1,40 +0,0 @@
1
- #!/usr/bin/env ruby -wW1
2
- # encoding: UTF-8
3
-
4
- $: << File.join(File.dirname(__FILE__), "../lib")
5
-
6
- require 'test/unit'
7
- require 'opee'
8
- require 'relay'
9
-
10
- class Opeet < ::Test::Unit::TestCase
11
-
12
- def test_ask_queue
13
- a = ::Relay.new(nil)
14
- assert_equal(0, a.queue_count())
15
- a.stop()
16
- a.ask(:relay, 7)
17
- assert_equal(1, a.queue_count())
18
- a.start()
19
- sleep(0.5)
20
- assert_equal(7, a.last_data)
21
- a.close()
22
- end
23
-
24
- def test_log
25
- #::Opee::Env.logger.ask(:severity=, Logger::INFO)
26
- ::Opee::Env.logger.severity= Logger::INFO
27
- ::Opee::Env.log(Logger::INFO, "hello")
28
- ::Opee::Env.each_actor { |a| puts a.to_s }
29
- sleep(0.2)
30
- end
31
-
32
- def test_wait_close
33
- a = ::Relay.new(nil)
34
- a.ask(:relay, 7)
35
- ::Opee::Env.wait_close()
36
- assert_equal(7, a.last_data)
37
- a.close()
38
- end
39
-
40
- end # Opeet