opee 1.0.1 → 1.0.2

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