drbqs 0.0.5 → 0.0.6
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.rdoc +6 -4
- data/VERSION +1 -1
- data/drbqs.gemspec +33 -7
- data/lib/drbqs/client.rb +50 -10
- data/lib/drbqs/connection.rb +13 -11
- data/lib/drbqs/message.rb +5 -40
- data/lib/drbqs/node_list.rb +41 -0
- data/lib/drbqs/queue.rb +2 -21
- data/lib/drbqs/server.rb +27 -0
- data/lib/drbqs/server_define.rb +0 -1
- data/lib/drbqs/task.rb +38 -0
- data/lib/drbqs/task_client.rb +39 -9
- data/lib/drbqs/task_generator.rb +74 -0
- data/lib/drbqs.rb +2 -0
- data/spec/connection_spec.rb +39 -0
- data/spec/manage_spec.rb +50 -0
- data/spec/message_spec.rb +71 -0
- data/spec/node_list_spec.rb +54 -0
- data/spec/queue_spec.rb +59 -0
- data/spec/server_define_spec.rb +34 -0
- data/spec/task_client_spec.rb +53 -0
- data/spec/task_generator_spec.rb +32 -0
- data/spec/task_spec.rb +21 -0
- data/spec/test/test1.rb +13 -0
- data/spec/test1_spec.rb +80 -0
- data/spec/test2_spec.rb +75 -0
- metadata +110 -65
- data/spec/drbqs_spec.rb +0 -7
data/README.rdoc
CHANGED
@@ -30,7 +30,7 @@ We make server.rb as the following.
|
|
30
30
|
|
31
31
|
require_relative 'sum.rb'
|
32
32
|
|
33
|
-
DRbQS.define_server do |server|
|
33
|
+
DRbQS.define_server do |server, argv, opts|
|
34
34
|
10.step(100, 10) do |i|
|
35
35
|
task = DRbQS::Task.new(Sum.new(i - 10, i), :exec)
|
36
36
|
server.queue.add(task)
|
@@ -47,13 +47,15 @@ In terminal, we load server.rb and execute server of drbqs.
|
|
47
47
|
|
48
48
|
=== Start node and connect server
|
49
49
|
|
50
|
-
|
50
|
+
Because nodes needs class Sum,
|
51
|
+
the nodes load sum.rb when they starts.
|
52
|
+
Then, we type in terminal.
|
51
53
|
|
52
|
-
drbqs-node druby://localhost:13500/
|
54
|
+
drbqs-node druby://localhost:13500/ -l sum.rb
|
53
55
|
|
54
56
|
To use two cpu cores we execute two processes by the following.
|
55
57
|
|
56
|
-
drbqs-node 2 druby://localhost:13500/
|
58
|
+
drbqs-node 2 druby://localhost:13500/ -l sum.rb
|
57
59
|
|
58
60
|
Then, if it succeeds, the calculation starts.
|
59
61
|
If it finishes, the server and node ends.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.6
|
data/drbqs.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{drbqs}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Takayuki YAMAGUCHI"]
|
12
|
-
s.date = %q{2011-03-
|
12
|
+
s.date = %q{2011-03-08}
|
13
13
|
s.description = %q{Task queuing system over network that is implemented by dRuby.}
|
14
14
|
s.email = %q{d@ytak.info}
|
15
15
|
s.executables = ["drbqs-manage", "drbqs-node", "drbqs-server"]
|
@@ -41,29 +41,55 @@ Gem::Specification.new do |s|
|
|
41
41
|
"lib/drbqs/connection.rb",
|
42
42
|
"lib/drbqs/manage.rb",
|
43
43
|
"lib/drbqs/message.rb",
|
44
|
+
"lib/drbqs/node_list.rb",
|
44
45
|
"lib/drbqs/queue.rb",
|
45
46
|
"lib/drbqs/server.rb",
|
46
47
|
"lib/drbqs/server_define.rb",
|
48
|
+
"lib/drbqs/task.rb",
|
47
49
|
"lib/drbqs/task_client.rb",
|
50
|
+
"lib/drbqs/task_generator.rb",
|
48
51
|
"spec/acl_file_spec.rb",
|
52
|
+
"spec/connection_spec.rb",
|
49
53
|
"spec/data/acl.txt",
|
50
|
-
"spec/
|
54
|
+
"spec/manage_spec.rb",
|
55
|
+
"spec/message_spec.rb",
|
56
|
+
"spec/node_list_spec.rb",
|
57
|
+
"spec/queue_spec.rb",
|
58
|
+
"spec/server_define_spec.rb",
|
51
59
|
"spec/server_spec.rb",
|
52
|
-
"spec/spec_helper.rb"
|
60
|
+
"spec/spec_helper.rb",
|
61
|
+
"spec/task_client_spec.rb",
|
62
|
+
"spec/task_generator_spec.rb",
|
63
|
+
"spec/task_spec.rb",
|
64
|
+
"spec/test/test1.rb",
|
65
|
+
"spec/test1_spec.rb",
|
66
|
+
"spec/test2_spec.rb"
|
53
67
|
]
|
54
68
|
s.homepage = %q{http://github.com/ytaka/drbqs}
|
55
69
|
s.licenses = ["GPL3"]
|
56
70
|
s.require_paths = ["lib"]
|
57
|
-
s.rubygems_version = %q{1.
|
71
|
+
s.rubygems_version = %q{1.3.7}
|
58
72
|
s.summary = %q{dRuby Queueing System}
|
59
73
|
s.test_files = [
|
60
74
|
"spec/acl_file_spec.rb",
|
61
|
-
"spec/
|
75
|
+
"spec/connection_spec.rb",
|
76
|
+
"spec/manage_spec.rb",
|
77
|
+
"spec/message_spec.rb",
|
78
|
+
"spec/node_list_spec.rb",
|
79
|
+
"spec/queue_spec.rb",
|
80
|
+
"spec/server_define_spec.rb",
|
62
81
|
"spec/server_spec.rb",
|
63
|
-
"spec/spec_helper.rb"
|
82
|
+
"spec/spec_helper.rb",
|
83
|
+
"spec/task_client_spec.rb",
|
84
|
+
"spec/task_generator_spec.rb",
|
85
|
+
"spec/task_spec.rb",
|
86
|
+
"spec/test/test1.rb",
|
87
|
+
"spec/test1_spec.rb",
|
88
|
+
"spec/test2_spec.rb"
|
64
89
|
]
|
65
90
|
|
66
91
|
if s.respond_to? :specification_version then
|
92
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
67
93
|
s.specification_version = 3
|
68
94
|
|
69
95
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
data/lib/drbqs/client.rb
CHANGED
@@ -4,12 +4,18 @@ require 'drbqs/task_client'
|
|
4
4
|
module DRbQS
|
5
5
|
|
6
6
|
class Client
|
7
|
+
|
8
|
+
WAIT_NEW_TASK = 1
|
9
|
+
OUTPUT_NOT_SEND_RESULT = 'not_send_result'
|
10
|
+
|
11
|
+
# :continue
|
7
12
|
def initialize(access_uri, opts = {})
|
8
13
|
@access_uri = access_uri
|
9
14
|
@logger = Logger.new(opts[:log_file] || 'drbqs_client.log')
|
10
15
|
@logger.level = opts[:log_level] || Logger::ERROR
|
11
16
|
@connection = nil
|
12
17
|
@task_client = nil
|
18
|
+
@process_continue = opts[:continue]
|
13
19
|
end
|
14
20
|
|
15
21
|
def execute_task(marshal_obj, method_sym, args)
|
@@ -28,21 +34,55 @@ module DRbQS
|
|
28
34
|
end
|
29
35
|
end
|
30
36
|
|
31
|
-
|
37
|
+
def dump_not_send_result_to_file
|
38
|
+
if data = @task_client.dump_result_queue
|
39
|
+
path = OUTPUT_NOT_SEND_RESULT + Time.now.to_i.to_s + '.dat'
|
40
|
+
open(path, 'w') { |f| f.print data }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
private :dump_not_send_result_to_file
|
44
|
+
|
45
|
+
def output_error(err)
|
46
|
+
if @logger
|
47
|
+
@logger.error("Raise error in calculating thread: #{err.to_s}") { "\n" + err.backtrace.join("\n") }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
private :output_error
|
51
|
+
|
52
|
+
def process_exit
|
53
|
+
dump_not_send_result_to_file
|
54
|
+
unless @process_continue
|
55
|
+
Kernel.exit
|
56
|
+
end
|
57
|
+
end
|
58
|
+
private :process_exit
|
32
59
|
|
33
|
-
def calculate
|
60
|
+
def calculate(opts = {})
|
34
61
|
cn = Thread.new do
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
62
|
+
begin
|
63
|
+
loop do
|
64
|
+
@task_client.add_new_task
|
65
|
+
if @connection.respond_alive_signal == :exit
|
66
|
+
break
|
67
|
+
end
|
68
|
+
@task_client.send_result
|
69
|
+
sleep(WAIT_NEW_TASK)
|
70
|
+
end
|
71
|
+
rescue => err
|
72
|
+
output_error(err)
|
73
|
+
ensure
|
74
|
+
process_exit
|
40
75
|
end
|
41
76
|
end
|
42
77
|
exec = Thread.new do
|
43
|
-
|
44
|
-
|
45
|
-
|
78
|
+
begin
|
79
|
+
loop do
|
80
|
+
marshal_obj, method_sym, args = @task_client.dequeue_task
|
81
|
+
@task_client.queue_result(execute_task(marshal_obj, method_sym, args))
|
82
|
+
end
|
83
|
+
rescue => err
|
84
|
+
output_error(err)
|
85
|
+
process_exit
|
46
86
|
end
|
47
87
|
end
|
48
88
|
cn.join
|
data/lib/drbqs/connection.rb
CHANGED
@@ -6,21 +6,23 @@ module DRbQS
|
|
6
6
|
def initialize(message, logger = nil)
|
7
7
|
@message = message
|
8
8
|
@logger = logger
|
9
|
-
@
|
9
|
+
@id_number = nil
|
10
|
+
@id_string = create_id_string
|
10
11
|
end
|
11
12
|
|
12
13
|
def create_id_string
|
13
14
|
t = Time.now
|
14
|
-
sprintf("
|
15
|
+
sprintf("%d%d%d:#{Socket.gethostname}", t.to_i, t.usec, rand(1000))
|
15
16
|
end
|
16
17
|
private :create_id_string
|
17
18
|
|
18
19
|
def get_id
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
unless @id_number
|
21
|
+
@message.write([:connect, @id_string])
|
22
|
+
@id_number = @message.take([@id_string, Fixnum])[1]
|
23
|
+
@logger.info("Get node id: #{@id_number}") if @logger
|
24
|
+
end
|
25
|
+
@id_number
|
24
26
|
end
|
25
27
|
|
26
28
|
def get_initialization
|
@@ -34,14 +36,14 @@ module DRbQS
|
|
34
36
|
|
35
37
|
def respond_alive_signal
|
36
38
|
begin
|
37
|
-
node_id, sym = @message.take([@
|
39
|
+
node_id, sym = @message.take([@id_number, Symbol], 0)
|
38
40
|
case sym
|
39
41
|
when :alive_p
|
40
|
-
@message.write([:alive, @
|
41
|
-
@logger.info("Send alive signal of node id #{@
|
42
|
+
@message.write([:alive, @id_number])
|
43
|
+
@logger.info("Send alive signal of node id #{@id_number}") if @logger
|
42
44
|
when :exit
|
43
45
|
@logger.info("Get exit signal") if @logger
|
44
|
-
|
46
|
+
return :exit
|
45
47
|
end
|
46
48
|
rescue Rinda::RequestExpiredError
|
47
49
|
end
|
data/lib/drbqs/message.rb
CHANGED
@@ -1,43 +1,6 @@
|
|
1
|
-
|
2
|
-
class NodeList
|
3
|
-
def initialize
|
4
|
-
@id = 0
|
5
|
-
@list = {}
|
6
|
-
@check = []
|
7
|
-
end
|
8
|
-
|
9
|
-
def get_new_id(id_str)
|
10
|
-
@id += 1
|
11
|
-
@list[@id] = id_str
|
12
|
-
@id
|
13
|
-
end
|
14
|
-
|
15
|
-
def each(&block)
|
16
|
-
@list.each(&block)
|
17
|
-
end
|
18
|
-
|
19
|
-
def set_check_connection
|
20
|
-
@check = @list.keys
|
21
|
-
end
|
22
|
-
|
23
|
-
def delete_not_alive
|
24
|
-
@check.each do |id|
|
25
|
-
@list.delete(id)
|
26
|
-
end
|
27
|
-
deleted = @check
|
28
|
-
@check = []
|
29
|
-
deleted
|
30
|
-
end
|
31
|
-
|
32
|
-
def set_alive(id)
|
33
|
-
@check.delete(id)
|
34
|
-
end
|
35
|
-
|
36
|
-
def empty?
|
37
|
-
@list.size == 0
|
38
|
-
end
|
39
|
-
end
|
1
|
+
require 'drbqs/node_list'
|
40
2
|
|
3
|
+
module DRbQS
|
41
4
|
class MessageServer
|
42
5
|
def initialize(message, logger = nil)
|
43
6
|
@message = message
|
@@ -50,6 +13,7 @@ module DRbQS
|
|
50
13
|
mes = @message.take([Symbol, nil], 0)
|
51
14
|
manage_message(*mes)
|
52
15
|
rescue Rinda::RequestExpiredError
|
16
|
+
nil
|
53
17
|
end
|
54
18
|
end
|
55
19
|
|
@@ -66,7 +30,8 @@ module DRbQS
|
|
66
30
|
@logger.info("Get exit message from #{arg.to_s}") if @logger
|
67
31
|
return :exit_server
|
68
32
|
else
|
69
|
-
|
33
|
+
@logger.error("Invalid message from #{arg.to_s}") if @logger
|
34
|
+
return nil
|
70
35
|
end
|
71
36
|
end
|
72
37
|
private :manage_message
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module DRbQS
|
2
|
+
class NodeList
|
3
|
+
def initialize
|
4
|
+
@id = 0
|
5
|
+
@list = {}
|
6
|
+
@check = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_new_id(id_str)
|
10
|
+
@id += 1
|
11
|
+
@list[@id] = id_str
|
12
|
+
@id
|
13
|
+
end
|
14
|
+
|
15
|
+
def each(&block)
|
16
|
+
@list.each(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_check_connection
|
20
|
+
@check = @list.keys
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete_not_alive
|
24
|
+
@check.each do |id|
|
25
|
+
@list.delete(id)
|
26
|
+
end
|
27
|
+
deleted = @check
|
28
|
+
@check = []
|
29
|
+
deleted
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_alive(id)
|
33
|
+
@check.delete(id)
|
34
|
+
end
|
35
|
+
|
36
|
+
def empty?
|
37
|
+
@list.size == 0
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/lib/drbqs/queue.rb
CHANGED
@@ -1,25 +1,4 @@
|
|
1
1
|
module DRbQS
|
2
|
-
class Task
|
3
|
-
attr_reader :hook
|
4
|
-
|
5
|
-
def initialize(obj, method_sym, args = [], &hook)
|
6
|
-
begin
|
7
|
-
@marshal_obj = Marshal.dump(obj)
|
8
|
-
rescue
|
9
|
-
raise "Can not dump an instance of #{obj.class}."
|
10
|
-
end
|
11
|
-
unless Array === args
|
12
|
-
raise "Arguments of task must be an array."
|
13
|
-
end
|
14
|
-
@method_sym = method_sym.intern
|
15
|
-
@args = args
|
16
|
-
@hook = hook
|
17
|
-
end
|
18
|
-
|
19
|
-
def drb_args(task_id)
|
20
|
-
[task_id, @marshal_obj, @method_sym, @args]
|
21
|
-
end
|
22
|
-
end
|
23
2
|
|
24
3
|
class QueueServer
|
25
4
|
|
@@ -38,11 +17,13 @@ module DRbQS
|
|
38
17
|
private :queue_task
|
39
18
|
|
40
19
|
# &hook take two arguments: a QueueServer object and a result of task.
|
20
|
+
# Return task ID (for debug).
|
41
21
|
def add(task)
|
42
22
|
@task_id += 1
|
43
23
|
@logger.info("New task: #{@task_id}") if @logger
|
44
24
|
@cache[@task_id] = task
|
45
25
|
queue_task(@task_id)
|
26
|
+
@task_id
|
46
27
|
end
|
47
28
|
|
48
29
|
def get_accept_signal
|
data/lib/drbqs/server.rb
CHANGED
@@ -18,6 +18,8 @@ module DRbQS
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
# When we set both empty_queue_hook and task_generator,
|
22
|
+
# empty_queue_hook is prior to task_generator.
|
21
23
|
class Server
|
22
24
|
attr_reader :queue
|
23
25
|
|
@@ -43,6 +45,7 @@ module DRbQS
|
|
43
45
|
@message = MessageServer.new(@ts[:message], @logger)
|
44
46
|
@queue= QueueServer.new(@ts[:queue], @ts[:result], @logger)
|
45
47
|
@check_alive = CheckAlive.new(opts[:check_alive])
|
48
|
+
@task_generator = []
|
46
49
|
@empty_queue_hook = nil
|
47
50
|
end
|
48
51
|
|
@@ -74,10 +77,31 @@ module DRbQS
|
|
74
77
|
end
|
75
78
|
private :check_connection
|
76
79
|
|
80
|
+
def set_task_generator(task_generator)
|
81
|
+
@task_generator << task_generator
|
82
|
+
end
|
83
|
+
|
84
|
+
def add_tasks_from_generator
|
85
|
+
if @task_generator.size > 0 && @queue.empty?
|
86
|
+
if tasks = @task_generator[0].new_tasks
|
87
|
+
tasks.each { |t| @queue.add(t) }
|
88
|
+
@logger.debug("Generator add #{tasks.size} tasks.") if @logger
|
89
|
+
else
|
90
|
+
@task_generator.delete_at(0)
|
91
|
+
@logger.info("Generator creates all tasks and then has been deleted.") if @logger
|
92
|
+
if @task_generator.size > 0
|
93
|
+
add_tasks_from_generator
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
private :add_tasks_from_generator
|
99
|
+
|
77
100
|
def set_initialization_task(task)
|
78
101
|
@message.set_initialization(task)
|
79
102
|
end
|
80
103
|
|
104
|
+
# &block takes self as an argument.
|
81
105
|
def set_empty_queue_hook(&block)
|
82
106
|
if block_given?
|
83
107
|
@empty_queue_hook = block
|
@@ -86,6 +110,7 @@ module DRbQS
|
|
86
110
|
end
|
87
111
|
end
|
88
112
|
|
113
|
+
# &block takes self as an argument.
|
89
114
|
def set_finish_hook(&block)
|
90
115
|
if block_given?
|
91
116
|
@finish_hook = block
|
@@ -99,6 +124,7 @@ module DRbQS
|
|
99
124
|
@logger.info("Execute empty queue hook.") if @logger
|
100
125
|
@empty_queue_hook.call(self)
|
101
126
|
end
|
127
|
+
add_tasks_from_generator
|
102
128
|
if @finish_hook && @queue.finished?
|
103
129
|
@logger.info("Execute finish hook.") if @logger
|
104
130
|
@finish_hook.call(self)
|
@@ -132,6 +158,7 @@ module DRbQS
|
|
132
158
|
private :check_message
|
133
159
|
|
134
160
|
def wait
|
161
|
+
@task_generator.each { |tgen| tgen.init }
|
135
162
|
loop do
|
136
163
|
check_message
|
137
164
|
check_connection
|
data/lib/drbqs/server_define.rb
CHANGED
data/lib/drbqs/task.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module DRbQS
|
2
|
+
|
3
|
+
# The tasks defined by this class are sent to nodes and
|
4
|
+
# calculated by the nodes.
|
5
|
+
# After the node returns the result of calculation to server,
|
6
|
+
# the server execute the hook.
|
7
|
+
class Task
|
8
|
+
attr_reader :hook
|
9
|
+
|
10
|
+
# Nodes execute obj.method_sym(*args).
|
11
|
+
# Server executes &hook with a server instance and an array of result
|
12
|
+
# after the server accepts the results from nodes.
|
13
|
+
def initialize(obj, method_sym, args = [], &hook)
|
14
|
+
begin
|
15
|
+
@marshal_obj = Marshal.dump(obj)
|
16
|
+
rescue
|
17
|
+
raise "Can not dump an instance of #{obj.class}."
|
18
|
+
end
|
19
|
+
unless Array === args
|
20
|
+
raise "Arguments of task must be an array."
|
21
|
+
end
|
22
|
+
@method_sym = method_sym.intern
|
23
|
+
@args = args
|
24
|
+
@hook = hook
|
25
|
+
end
|
26
|
+
|
27
|
+
def drb_args(task_id)
|
28
|
+
[task_id, @marshal_obj, @method_sym, @args]
|
29
|
+
end
|
30
|
+
|
31
|
+
def same_target?(other)
|
32
|
+
@marshal_obj == other.instance_variable_get(:@marshal_obj) &&
|
33
|
+
@method_sym == other.instance_variable_get(:@method_sym) &&
|
34
|
+
@args == other.instance_variable_get(:@args)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/lib/drbqs/task_client.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module DRbQS
|
2
2
|
class TaskClient
|
3
|
+
attr_reader :node_id, :calculating_task
|
4
|
+
|
3
5
|
def initialize(node_id, queue, result, logger = nil)
|
4
6
|
@node_id = node_id
|
5
7
|
@queue = queue
|
@@ -10,12 +12,33 @@ module DRbQS
|
|
10
12
|
@logger = logger
|
11
13
|
end
|
12
14
|
|
15
|
+
def task_empty?
|
16
|
+
@task_queue.empty?
|
17
|
+
end
|
18
|
+
|
19
|
+
def result_empty?
|
20
|
+
@result_queue.empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
def dequeue_result
|
24
|
+
@result_queue.deq
|
25
|
+
end
|
26
|
+
private :dequeue_result
|
27
|
+
|
28
|
+
def queue_task(task_id, ary)
|
29
|
+
@task_queue.enq(ary)
|
30
|
+
@calculating_task = task_id
|
31
|
+
end
|
32
|
+
|
33
|
+
def dequeue_task
|
34
|
+
@task_queue.deq
|
35
|
+
end
|
36
|
+
|
13
37
|
def add_new_task
|
14
38
|
unless @calculating_task
|
15
39
|
begin
|
16
40
|
task_id, obj, method_sym, args = @queue.take([Fixnum, nil, Symbol, nil], 0)
|
17
|
-
|
18
|
-
@task_queue.enq([obj, method_sym, args])
|
41
|
+
queue_task(task_id, [obj, method_sym, args])
|
19
42
|
@logger.info("Send accept signal: node #{@node_id} caluclating #{@calculating_task}") if @logger
|
20
43
|
@result.write([:accept, @calculating_task, @node_id])
|
21
44
|
rescue Rinda::RequestExpiredError
|
@@ -24,22 +47,29 @@ module DRbQS
|
|
24
47
|
end
|
25
48
|
|
26
49
|
def send_result
|
27
|
-
if
|
28
|
-
result =
|
50
|
+
if !result_empty?
|
51
|
+
result = dequeue_result
|
29
52
|
@logger.info("Send result: #{@calculating_task}") { result.inspect } if @logger
|
30
53
|
@result.write([:result, @calculating_task, result])
|
31
54
|
@calculating_task = nil
|
32
55
|
end
|
33
56
|
end
|
34
57
|
|
35
|
-
def
|
36
|
-
@task_queue.deq
|
37
|
-
end
|
38
|
-
|
39
|
-
def transmit(result)
|
58
|
+
def queue_result(result)
|
40
59
|
@result_queue.enq(result)
|
41
60
|
end
|
42
61
|
|
62
|
+
def dump_result_queue
|
63
|
+
results = []
|
64
|
+
while !result_empty?
|
65
|
+
results << dequeue_result
|
66
|
+
end
|
67
|
+
if results.size > 0
|
68
|
+
Marshal.dump(results)
|
69
|
+
else
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
end
|
43
73
|
end
|
44
74
|
|
45
75
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module DRbQS
|
2
|
+
class TaskGenerator
|
3
|
+
def initialize(data = {})
|
4
|
+
data.each do |key, val|
|
5
|
+
instance_variable_set("@#{key.to_s}", val)
|
6
|
+
end
|
7
|
+
@__fiber__ = nil
|
8
|
+
@__iterate__ = nil
|
9
|
+
@__fiber_init__ = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def have_next?
|
13
|
+
!!@__fiber__
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_add_task(*args, &block)
|
17
|
+
Fiber.yield(DRbQS::Task.new(*args, &block))
|
18
|
+
end
|
19
|
+
|
20
|
+
def set(iterate = 1, &block)
|
21
|
+
@__iterate__ = iterate
|
22
|
+
@__fiber_init__ = lambda do
|
23
|
+
@__fiber__ = Fiber.new do
|
24
|
+
instance_eval(&block)
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def init
|
31
|
+
@__fiber_init__.call
|
32
|
+
end
|
33
|
+
|
34
|
+
# Return an array of new tasks.
|
35
|
+
def new_tasks
|
36
|
+
if @__fiber__
|
37
|
+
task_ary = []
|
38
|
+
@__iterate__.times do |i|
|
39
|
+
if task_new = @__fiber__.resume
|
40
|
+
case task_new
|
41
|
+
when DRbQS::Task
|
42
|
+
task_ary << task_new
|
43
|
+
when Array
|
44
|
+
task_ary.concat(task_new)
|
45
|
+
else
|
46
|
+
raise "Invalid type of new task."
|
47
|
+
end
|
48
|
+
else
|
49
|
+
@__fiber__ = nil
|
50
|
+
break
|
51
|
+
end
|
52
|
+
end
|
53
|
+
if task_ary.size > 0
|
54
|
+
return task_ary
|
55
|
+
end
|
56
|
+
end
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
|
60
|
+
# Create all tasks for test and return true if all tasks created properly.
|
61
|
+
def debug_all_tasks(limit = nil)
|
62
|
+
i = 0
|
63
|
+
while ary = new_tasks
|
64
|
+
ary.each? do |t|
|
65
|
+
unless DRbQS::TaskGenerator === t
|
66
|
+
raise "Invalid task by #{i}th generation: #{t.inspect}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
i += 1
|
70
|
+
end
|
71
|
+
true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/drbqs.rb
CHANGED
@@ -11,6 +11,8 @@ require 'drbqs/server_define'
|
|
11
11
|
module DRbQS
|
12
12
|
autoload :Server, 'drbqs/server'
|
13
13
|
autoload :Client, 'drbqs/client'
|
14
|
+
autoload :Task, 'drbqs/task'
|
15
|
+
autoload :TaskGenerator, 'drbqs/task_generator'
|
14
16
|
autoload :Manage, 'drbqs/manage'
|
15
17
|
|
16
18
|
ROOT_DEFAULT_PORT = 13500
|