dtr 0.0.4 → 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.
- data/CHANGES +7 -0
- data/LICENSE.txt +203 -0
- data/README.rdoc +208 -0
- data/Rakefile +64 -205
- data/TODO +8 -2
- data/bin/dtr +27 -60
- data/dtr.gemspec +8 -11
- data/lib/dtr.rb +5 -94
- data/lib/dtr/agent.rb +38 -0
- data/lib/dtr/agent/brain.rb +57 -0
- data/lib/dtr/agent/herald.rb +60 -0
- data/lib/dtr/agent/runner.rb +87 -0
- data/lib/dtr/agent/sync_codebase.rb +44 -0
- data/lib/dtr/agent/sync_logger.rb +70 -0
- data/lib/dtr/agent/test_case.rb +53 -0
- data/lib/dtr/agent/test_unit.rb +40 -0
- data/lib/dtr/agent/worker.rb +89 -0
- data/lib/dtr/agent/working_env_ext.rb +47 -0
- data/lib/dtr/facade.rb +65 -0
- data/lib/dtr/master.rb +40 -0
- data/lib/dtr/monitor.rb +95 -0
- data/lib/dtr/raketasks.rb +155 -22
- data/lib/dtr/shared.rb +24 -0
- data/lib/dtr/shared/adapter.rb +115 -0
- data/lib/dtr/shared/configuration.rb +104 -0
- data/lib/dtr/shared/message_decorator.rb +28 -0
- data/lib/dtr/shared/ruby_ext.rb +129 -0
- data/lib/dtr/shared/service.rb +19 -0
- data/lib/dtr/shared/service/agent.rb +37 -0
- data/lib/dtr/shared/service/file.rb +28 -0
- data/lib/dtr/shared/service/rinda.rb +48 -0
- data/lib/dtr/shared/service/runner.rb +34 -0
- data/lib/dtr/shared/service/working_env.rb +28 -0
- data/lib/dtr/shared/sync_codebase.rb +18 -0
- data/lib/dtr/shared/sync_codebase/copiable_package.rb +40 -0
- data/lib/dtr/shared/sync_codebase/master_ext.rb +40 -0
- data/lib/dtr/shared/sync_codebase/package.rb +53 -0
- data/lib/dtr/shared/sync_codebase/sync_service.rb +36 -0
- data/lib/dtr/shared/sync_logger.rb +64 -0
- data/lib/dtr/shared/utils.rb +17 -0
- data/lib/dtr/shared/utils/cmd.rb +30 -0
- data/lib/dtr/shared/utils/env_store.rb +60 -0
- data/lib/dtr/shared/utils/logger.rb +87 -0
- data/lib/dtr/shared/working_env.rb +38 -0
- data/lib/dtr/test_unit.rb +9 -275
- data/lib/dtr/test_unit/drb_test_runner.rb +48 -0
- data/lib/dtr/test_unit/injection.rb +29 -0
- data/lib/dtr/test_unit/test_case_injection.rb +37 -0
- data/lib/dtr/test_unit/test_suite_injection.rb +24 -0
- data/lib/dtr/test_unit/testrunnermediator_injection.rb +72 -0
- data/lib/dtr/test_unit/thread_safe_test_result.rb +38 -0
- data/lib/dtr/test_unit/worker_club.rb +72 -0
- data/lib/dtr/test_unit_injection.rb +1 -2
- data/test/acceptance/agent_working_env_test.rb +86 -0
- data/test/acceptance/dtr_package_task_test.rb +36 -0
- data/test/acceptance/general_test.rb +331 -0
- data/test/acceptance/raketasks_test.rb +23 -0
- data/test/acceptance/sync_codebase_test.rb +66 -0
- data/test/acceptance/sync_logger_test.rb +32 -0
- data/test/agent_helper.rb +37 -0
- data/test/logger_stub.rb +34 -0
- data/test/test_helper.rb +71 -0
- data/test/unit/adapter_test.rb +149 -0
- data/test/unit/configuration_test.rb +44 -0
- data/test/unit/facade_test.rb +41 -0
- data/test/unit/logger_test.rb +72 -0
- data/test/unit/test_unit_test.rb +26 -0
- data/test/unit/working_env_test.rb +71 -0
- data/testdata/Rakefile +11 -0
- data/testdata/a_failed_test_case.rb +8 -0
- data/testdata/a_file_system_test_case.rb +8 -0
- data/testdata/a_test_case.rb +13 -0
- data/testdata/a_test_case2.rb +6 -0
- data/testdata/an_error_test_case.rb +9 -0
- data/testdata/another_project/Rakefile +6 -0
- data/testdata/another_project/passed_test_case.rb +7 -0
- data/testdata/hacked_run_method_test_case.rb +15 -0
- data/testdata/is_required_by_a_test.rb +9 -0
- data/testdata/lib/lib_test_case.rb +7 -0
- data/testdata/package_task_test_rakefile +8 -0
- data/testdata/raketasks/Rakefile +7 -0
- data/testdata/raketasks/success_test_case.rb +6 -0
- data/testdata/scenario_test_case.rb +34 -0
- data/testdata/setup_agent_env_test_case.rb +9 -0
- data/testdata/sleep_3_secs_test_case.rb +9 -0
- data/testdata/verify_dir_pwd/Rakefile +6 -0
- data/testdata/verify_dir_pwd/verify_dir_pwd_test_case.rb +10 -0
- metadata +101 -34
- data/README +0 -291
- data/install.rb +0 -88
- data/lib/dtr/base.rb +0 -172
- data/lib/dtr/runner.rb +0 -270
- data/lib/dtr/service_provider.rb +0 -160
data/lib/dtr/master.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'dtr/shared'
|
16
|
+
|
17
|
+
module DTR
|
18
|
+
module Master
|
19
|
+
def with_dtr_master(&block)
|
20
|
+
if defined?(ActiveRecord::Base)
|
21
|
+
ActiveRecord::Base.clear_active_connections! rescue nil
|
22
|
+
end
|
23
|
+
|
24
|
+
DTR.info {""}
|
25
|
+
DTR.info {"--------------------beautiful line--------------------------"}
|
26
|
+
DTR.info {"Master process started at #{Time.now}"}
|
27
|
+
|
28
|
+
DTR.configuration.with_rinda_server do
|
29
|
+
provide_working_env WorkingEnv.new
|
30
|
+
with_wakeup_agents(&block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
include Adapter::Master
|
35
|
+
include Service::WorkingEnv
|
36
|
+
include SyncCodebase::MasterExt
|
37
|
+
end
|
38
|
+
|
39
|
+
Configuration.send(:include, SyncLogger::Provider)
|
40
|
+
end
|
data/lib/dtr/monitor.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'dtr/master'
|
16
|
+
|
17
|
+
module DTR
|
18
|
+
|
19
|
+
# Monitor provides a way to monitor agent/master process working status.
|
20
|
+
class Monitor
|
21
|
+
|
22
|
+
class AgentsMonitor
|
23
|
+
include Adapter::Master
|
24
|
+
|
25
|
+
def start
|
26
|
+
DTR.fork_process do
|
27
|
+
monitor
|
28
|
+
end
|
29
|
+
end
|
30
|
+
def monitor
|
31
|
+
DTR.configuration.with_rinda_server do
|
32
|
+
with_wakeup_agents do
|
33
|
+
begin
|
34
|
+
sleep
|
35
|
+
rescue Interrupt
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class MasterMonitor
|
43
|
+
include Adapter::Follower
|
44
|
+
include Service::Agent
|
45
|
+
|
46
|
+
def start
|
47
|
+
DTR.fork_process do
|
48
|
+
begin
|
49
|
+
loop do
|
50
|
+
monitor
|
51
|
+
end
|
52
|
+
rescue Errno::EADDRINUSE
|
53
|
+
puts "There is DTR agent started on this machine."
|
54
|
+
puts "Shutdown it for monitoring working DTR Master info."
|
55
|
+
rescue Interrupt
|
56
|
+
ensure
|
57
|
+
relax
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def monitor
|
63
|
+
msg, from_host, group = listen
|
64
|
+
unless ["127.0.0.1:#{DTR.configuration.rinda_server_port}"].include?(from_host)
|
65
|
+
puts "Master process message from #{from_host}: #{msg} for group #{group}"
|
66
|
+
ip, port = from_host.split(':')
|
67
|
+
with_configuration(ip, port) do
|
68
|
+
start_service
|
69
|
+
puts "Agents working for #{from_host}: "
|
70
|
+
puts all_agents_info.collect{|i| " #{i.strip}"}.join("\n")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def with_configuration(ip, port)
|
76
|
+
my_port = DTR.configuration.rinda_server_port
|
77
|
+
my_broadcast_list = DTR.configuration.broadcast_list
|
78
|
+
DTR.configuration.rinda_server_port = port.to_i
|
79
|
+
DTR.configuration.broadcast_list = [ip]
|
80
|
+
yield
|
81
|
+
ensure
|
82
|
+
DTR.configuration.broadcast_list = my_broadcast_list
|
83
|
+
DTR.configuration.rinda_server_port = my_port
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def start
|
88
|
+
MasterMonitor.new.start
|
89
|
+
AgentsMonitor.new.start
|
90
|
+
puts "Monitor process started at #{Time.now}"
|
91
|
+
Process.waitall
|
92
|
+
rescue Interrupt
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/dtr/raketasks.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-2008 Li Xiao
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -13,21 +13,79 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
require "rubygems"
|
16
|
-
require '
|
16
|
+
require 'rake'
|
17
17
|
require 'rake/testtask'
|
18
|
+
require 'rake/tasklib'
|
19
|
+
|
20
|
+
require 'dtr'
|
21
|
+
require 'dtr/shared/ruby_ext'
|
22
|
+
require 'dtr/shared/utils'
|
23
|
+
require 'dtr/shared/sync_codebase/package'
|
18
24
|
|
19
25
|
module DTR
|
20
|
-
|
21
|
-
|
22
|
-
|
26
|
+
# Create tasks that run a set of tests with DTR injected.
|
27
|
+
# The TestTask will create the following targets:
|
28
|
+
#
|
29
|
+
# [<b>:dtr</b>]:
|
30
|
+
# Create a task that runs a set of tests by DTR master.
|
31
|
+
#
|
32
|
+
# [DTR::PackageTask]:
|
33
|
+
# Create a packaging task that will package the project into
|
34
|
+
# distributable files for running test on remote machine.
|
35
|
+
# All test files should be included.
|
36
|
+
#
|
37
|
+
# Example:
|
38
|
+
# require 'dtr/raketasks'
|
39
|
+
#
|
40
|
+
# DTR::TestTask.new do |t|
|
41
|
+
# t.libs << "test"
|
42
|
+
# t.test_files = FileList['test/test*.rb']
|
43
|
+
# t.verbose = true
|
44
|
+
# t.processes = 1 # default is 1
|
45
|
+
# t.package_files.include("lib/**/*") # default is FileList["**/*"]
|
46
|
+
# t.package_files.include("test/**/*")
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# This task inherits from Rake::TestTask, and adds 2 DTR specific
|
50
|
+
# options: processes and package_files.
|
51
|
+
#
|
52
|
+
class TestTask < Rake::TestTask
|
53
|
+
|
54
|
+
#
|
55
|
+
# The option processes is used to start an DTR agent in same directory
|
56
|
+
# with master process. The number of processes is the size of runners
|
57
|
+
# launched by agent for running tests. If processes is set to 0,
|
58
|
+
# then there is no agent started locally.
|
59
|
+
# Default is 1.
|
60
|
+
attr_accessor :processes
|
61
|
+
|
62
|
+
# List of files to be included in the package for running tests on
|
63
|
+
# remote agent.
|
64
|
+
# The agent, which starts in same directory on same machine with
|
65
|
+
# master process, would skip copying codebase.
|
66
|
+
# The default package files is Rake::FileList["**/*"].
|
67
|
+
attr_accessor :package_files
|
68
|
+
|
69
|
+
def initialize(name=:dtr)
|
70
|
+
@processes = 1
|
71
|
+
@package_files = Rake::FileList.new
|
72
|
+
super(name)
|
73
|
+
end
|
74
|
+
|
23
75
|
def define
|
76
|
+
PackageTask.new do |p|
|
77
|
+
p.package_files = package_files
|
78
|
+
if p.package_files.empty?
|
79
|
+
p.package_files.include("**/*")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
24
83
|
@libs.unshift DTR.lib_path
|
25
84
|
lib_path = @libs.join(File::PATH_SEPARATOR)
|
26
85
|
|
27
|
-
desc "Run tests
|
86
|
+
desc "Run tests with DTR injected"
|
28
87
|
task @name do
|
29
|
-
|
30
|
-
start_runners
|
88
|
+
@agent = start_agent
|
31
89
|
run_code = ''
|
32
90
|
begin
|
33
91
|
RakeFileUtils.verbose(@verbose) do
|
@@ -41,29 +99,104 @@ module DTR
|
|
41
99
|
" #{option_list}"
|
42
100
|
end
|
43
101
|
ensure
|
44
|
-
|
45
|
-
|
46
|
-
DTR.stop_server_daemon_mode rescue nil
|
102
|
+
if defined?(@agent)
|
103
|
+
DTR.kill_process @agent
|
47
104
|
end
|
48
105
|
end
|
49
106
|
end
|
50
107
|
self
|
51
108
|
end
|
52
|
-
|
53
|
-
def processes
|
54
|
-
@processes ? @processes.to_i : 2
|
55
|
-
end
|
56
|
-
|
57
|
-
def start_server?
|
58
|
-
defined?(@start_server) ? @start_server : true
|
59
|
-
end
|
60
|
-
|
109
|
+
|
61
110
|
private
|
62
|
-
def
|
111
|
+
def start_agent
|
63
112
|
return if self.processes.to_i <= 0
|
64
113
|
runner_names = []
|
65
114
|
self.processes.to_i.times {|i| runner_names << "runner#{i}"}
|
66
|
-
|
115
|
+
|
116
|
+
DTR.fork_process do
|
117
|
+
DTR_AGENT_OPTIONS[:runners] = runner_names if DTR_AGENT_OPTIONS[:runners].empty?
|
118
|
+
DTR.start_agent
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Create a packaging task that will package the project into
|
124
|
+
# distributable files for running test on remote machine.
|
125
|
+
# It uses zip and unzip to package and unpackage files.
|
126
|
+
# All test files should be included.
|
127
|
+
#
|
128
|
+
# The PackageTask will create the following targets:
|
129
|
+
#
|
130
|
+
# [<b>:dtr_package</b>]
|
131
|
+
# Create all the requested package files.
|
132
|
+
#
|
133
|
+
# [<b>:dtr_clobber_package</b>]
|
134
|
+
# Delete all the package files. This target is automatically
|
135
|
+
# added to the main clobber target.
|
136
|
+
#
|
137
|
+
# [<b>:dtr_repackage</b>]
|
138
|
+
# Rebuild the package files from scratch, even if they are not out
|
139
|
+
# of date.
|
140
|
+
#
|
141
|
+
# Example:
|
142
|
+
#
|
143
|
+
# DTR::PackageTask.new do |p|
|
144
|
+
# p.package_files.include("lib/**/*.rb")
|
145
|
+
# p.package_files.include("test/**/*.rb")
|
146
|
+
# end
|
147
|
+
#
|
148
|
+
class PackageTask < Rake::TaskLib
|
149
|
+
include SyncCodebase::Package
|
150
|
+
# List of files to be included in the package.
|
151
|
+
attr_accessor :package_files
|
152
|
+
|
153
|
+
# Create a Package Task with the given name and version.
|
154
|
+
def initialize
|
155
|
+
@package_files = Rake::FileList.new
|
156
|
+
yield self if block_given?
|
157
|
+
define
|
158
|
+
end
|
159
|
+
|
160
|
+
# Create the tasks defined by this task library.
|
161
|
+
def define
|
162
|
+
desc "Build packages for dtr task"
|
163
|
+
task :dtr_package
|
164
|
+
|
165
|
+
desc "Force a rebuild of the package files for dtr task"
|
166
|
+
task :dtr_repackage => [:dtr_clobber_package, :dtr_package]
|
167
|
+
|
168
|
+
desc "Remove package for dtr task"
|
169
|
+
task :dtr_clobber_package do
|
170
|
+
rm_r package_dir rescue nil
|
171
|
+
end
|
172
|
+
|
173
|
+
file, flag = package_file, 'j'
|
174
|
+
task :dtr_package => ["#{package_dir}/#{file}"]
|
175
|
+
|
176
|
+
file "#{package_dir}/#{file}" => [package_dir_path] do
|
177
|
+
chdir(package_dir) do
|
178
|
+
do_work(package_cmd)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
directory package_dir
|
183
|
+
|
184
|
+
file package_dir_path do
|
185
|
+
mkdir_p package_dir rescue nil
|
186
|
+
@package_files.exclude(package_dir)
|
187
|
+
@package_files.each do |fn|
|
188
|
+
f = File.join(package_dir_path, fn)
|
189
|
+
fdir = File.dirname(f)
|
190
|
+
mkdir_p(fdir) if !File.exist?(fdir)
|
191
|
+
if File.directory?(fn)
|
192
|
+
mkdir_p(f)
|
193
|
+
else
|
194
|
+
rm_f f
|
195
|
+
safe_ln(fn, f)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
self
|
67
200
|
end
|
68
201
|
end
|
69
202
|
end
|
data/lib/dtr/shared.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'fileutils'
|
16
|
+
require 'dtr/shared/ruby_ext'
|
17
|
+
require 'dtr/shared/utils'
|
18
|
+
require 'dtr/shared/message_decorator'
|
19
|
+
require 'dtr/shared/working_env'
|
20
|
+
require 'dtr/shared/service'
|
21
|
+
require 'dtr/shared/configuration'
|
22
|
+
require 'dtr/shared/sync_logger'
|
23
|
+
require 'dtr/shared/adapter'
|
24
|
+
require 'dtr/shared/sync_codebase'
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'timeout'
|
16
|
+
|
17
|
+
module DTR
|
18
|
+
module Adapter
|
19
|
+
WAKEUP_MESSAGE = 'wakeup'
|
20
|
+
SLEEP_MESSAGE = 'sleep'
|
21
|
+
|
22
|
+
module Follower
|
23
|
+
def wakeup?
|
24
|
+
msg, host, group = listen
|
25
|
+
if group == DTR.configuration.group && msg == Adapter::WAKEUP_MESSAGE
|
26
|
+
ip, port = host.split(':')
|
27
|
+
DTR.configuration.rinda_server_port = port.to_i
|
28
|
+
DTR.configuration.broadcast_list = [ip]
|
29
|
+
@wakeup_for_host = host
|
30
|
+
true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def sleep?
|
35
|
+
return true unless defined?(@wakeup_for_host)
|
36
|
+
Timeout.timeout(DTR.configuration.follower_listen_heartbeat_timeout) do
|
37
|
+
until (msg, host = listen) && host == @wakeup_for_host; end
|
38
|
+
msg == Adapter::SLEEP_MESSAGE
|
39
|
+
end
|
40
|
+
rescue Timeout::Error => e
|
41
|
+
DTR.info {"Timeout while listening command"}
|
42
|
+
true
|
43
|
+
end
|
44
|
+
|
45
|
+
def relax
|
46
|
+
if defined?(@soc) && @soc
|
47
|
+
@soc.close rescue nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def listen
|
53
|
+
unless defined?(@soc)
|
54
|
+
@soc = UDPSocket.open
|
55
|
+
@soc.bind('', DTR.configuration.agent_listen_port)
|
56
|
+
DTR.info("DTR Agent is listening on port #{DTR.configuration.agent_listen_port}")
|
57
|
+
end
|
58
|
+
message, client_address = @soc.recvfrom(400)
|
59
|
+
cmd, port, group = message.split
|
60
|
+
|
61
|
+
hostname = client_address[2]
|
62
|
+
host_ip = client_address[3]
|
63
|
+
DTR.info {"Received: #{cmd} for group #{group} from #{hostname}(#{host_ip}):#{port}"}
|
64
|
+
[cmd, "#{host_ip}:#{port}", group]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
module Master
|
69
|
+
def hypnotize_agents
|
70
|
+
yell_agents("#{Adapter::SLEEP_MESSAGE} #{DTR.configuration.rinda_server_port}")
|
71
|
+
end
|
72
|
+
|
73
|
+
def with_wakeup_agents(&block)
|
74
|
+
heartbeat = Thread.new do
|
75
|
+
loop do
|
76
|
+
do_wakeup_agents
|
77
|
+
sleep(DTR.configuration.master_heartbeat_interval)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
#heartbeat thread should have high priority for agent is listening
|
81
|
+
heartbeat.priority = Thread.current.priority + 10
|
82
|
+
block.call
|
83
|
+
ensure
|
84
|
+
#kill heartbeat first, so that agents wouldn't be wakeup after hypnotized
|
85
|
+
Thread.kill heartbeat rescue nil
|
86
|
+
hypnotize_agents rescue nil
|
87
|
+
end
|
88
|
+
|
89
|
+
def do_wakeup_agents
|
90
|
+
yell_agents("#{Adapter::WAKEUP_MESSAGE} #{DTR.configuration.rinda_server_port} #{DTR.configuration.group}")
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
def yell_agents(msg)
|
95
|
+
DTR.info {"yell agents #{msg}: #{DTR.configuration.broadcast_list.inspect}"}
|
96
|
+
DTR.configuration.broadcast_list.each do |it|
|
97
|
+
broadcast(it, msg)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def broadcast(it, msg)
|
102
|
+
soc = UDPSocket.open
|
103
|
+
begin
|
104
|
+
soc.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
|
105
|
+
DTR.debug {"broadcast sending #{msg} to #{it}"}
|
106
|
+
soc.send(msg, 0, it, DTR.configuration.agent_listen_port)
|
107
|
+
rescue
|
108
|
+
nil
|
109
|
+
ensure
|
110
|
+
soc.close
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|