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 +2 -2
- data/lib/opee.rb +2 -0
- data/lib/opee/actor.rb +1 -1
- data/lib/opee/askqueue.rb +29 -0
- data/lib/opee/env.rb +0 -1
- data/lib/opee/queue.rb +94 -0
- data/lib/opee/version.rb +1 -1
- data/lib/opee/workqueue.rb +5 -66
- metadata +4 -3
- data/test/tests.rb +0 -40
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.
|
27
|
+
### Release 1.0.2
|
28
28
|
|
29
|
-
-
|
29
|
+
- Added AskQueue which serves up method invocations instead of jobs.
|
30
30
|
|
31
31
|
# Plans and Notes
|
32
32
|
|
data/lib/opee.rb
CHANGED
data/lib/opee/actor.rb
CHANGED
@@ -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("
|
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
|
data/lib/opee/env.rb
CHANGED
data/lib/opee/queue.rb
ADDED
@@ -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
|
data/lib/opee/version.rb
CHANGED
data/lib/opee/workqueue.rb
CHANGED
@@ -1,26 +1,15 @@
|
|
1
1
|
|
2
2
|
module Opee
|
3
|
-
# Implements a work queue Actor 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 <
|
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
|
-
#
|
89
|
-
|
90
|
-
|
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.
|
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-
|
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
|
data/test/tests.rb
DELETED
@@ -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
|