skynet 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/History.txt +99 -0
  2. data/Manifest.txt +10 -9
  3. data/README.txt +74 -7
  4. data/app_generators/skynet_install/skynet_install_generator.rb +26 -22
  5. data/app_generators/skynet_install/templates/migration.rb +11 -5
  6. data/app_generators/skynet_install/templates/skynet +25 -12
  7. data/app_generators/skynet_install/templates/skynet_schema.sql +56 -0
  8. data/bin/skynet +26 -2
  9. data/bin/skynet_install +24 -0
  10. data/bin/skynet_tuplespace_server +13 -0
  11. data/config/hoe.rb +1 -0
  12. data/lib/skynet.rb +3 -0
  13. data/lib/skynet/mapreduce_helper.rb +74 -0
  14. data/lib/skynet/message_queue_adapters/mysql.rb +225 -172
  15. data/lib/skynet/message_queue_adapters/tuple_space.rb +31 -16
  16. data/lib/skynet/skynet_active_record_extensions.rb +78 -46
  17. data/lib/skynet/skynet_config.rb +162 -23
  18. data/lib/skynet/skynet_console.rb +23 -10
  19. data/lib/skynet/skynet_console_helper.rb +61 -58
  20. data/lib/skynet/skynet_job.rb +741 -493
  21. data/lib/skynet/skynet_launcher.rb +5 -1
  22. data/lib/skynet/skynet_manager.rb +106 -49
  23. data/lib/skynet/skynet_message.rb +169 -174
  24. data/lib/skynet/skynet_message_queue.rb +29 -16
  25. data/lib/skynet/skynet_partitioners.rb +92 -0
  26. data/lib/skynet/skynet_ruby_extensions.rb +3 -4
  27. data/lib/skynet/skynet_task.rb +61 -19
  28. data/lib/skynet/skynet_tuplespace_server.rb +0 -2
  29. data/lib/skynet/skynet_worker.rb +73 -51
  30. data/lib/skynet/version.rb +1 -1
  31. data/test/test_active_record_extensions.rb +138 -0
  32. data/test/test_helper.rb +6 -0
  33. data/test/{mysql_message_queue_adaptor_test.rb → test_mysql_message_queue_adapter.rb} +94 -30
  34. data/test/test_skynet.rb +11 -11
  35. data/test/test_skynet_install_generator.rb +0 -4
  36. data/test/test_skynet_job.rb +717 -0
  37. data/test/test_skynet_manager.rb +142 -0
  38. data/test/test_skynet_message.rb +229 -0
  39. data/test/test_skynet_task.rb +24 -0
  40. data/test/{tuplespace_message_queue_test.rb → test_tuplespace_message_queue.rb} +25 -30
  41. data/website/index.html +56 -16
  42. data/website/index.txt +55 -25
  43. data/website/template.rhtml +1 -1
  44. metadata +29 -13
  45. data/app_generators/skynet_install/templates/skynet_console +0 -16
  46. data/bin/skynet_console +0 -9
  47. data/sometest.rb +0 -23
  48. data/test/all_models_test.rb +0 -139
  49. data/test/skynet_manager_test.rb +0 -107
  50. data/test/skynet_message_test.rb +0 -42
  51. data/tmtags +0 -1242
@@ -0,0 +1,142 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class SkynetManagerTest < Test::Unit::TestCase
4
+
5
+ PIDS = []
6
+ PIDFILE = []
7
+
8
+ def setup
9
+ Skynet.configure(
10
+ :ENABLE => false,
11
+ # :SKYNET_PIDS_FILE => File.expand_path("#{RAILS_ROOT}/log/skynet_#{RAILS_ENV}.pids"),
12
+ :SKYNET_LOG_FILE => STDOUT,
13
+ :SKYNET_LOG_LEVEL => 4,
14
+ :MESSAGE_QUEUE_ADAPTER => "Skynet::MessageQueueAdapter::Mysql",
15
+ :MYSQL_TEMPERATURE_CHANGE_SLEEP => 1,
16
+ :MYSQL_NEXT_TASK_TIMEOUT => 1
17
+ )
18
+ ActiveRecord::Base.establish_connection(
19
+ :adapter => "mysql",
20
+ :host => "localhost",
21
+ :username => "root",
22
+ :password => "",
23
+ :database => "skynet_test"
24
+ )
25
+
26
+ mq.clear_outstanding_tasks
27
+ mq.clear_worker_status
28
+
29
+ @pids = []
30
+ @pidfile = []
31
+ @worker_queue = []
32
+
33
+ PIDS.delete_if {true}
34
+ PIDFILE.delete_if {true}
35
+
36
+ Process.stubs(:detatch).returns(true)
37
+ Process.stubs(:kill).returns(true)
38
+
39
+ @minstance = Skynet::Manager.any_instance
40
+ @hostname = Socket.gethostname
41
+
42
+ Skynet::Worker.any_instance.stubs(:max_memory_reached?).returns(false)
43
+ end
44
+
45
+ def setup_manager
46
+ @manager = Skynet::Manager.new(:script_path => "path", :workers => 2)
47
+ @manager.extend(Functor)
48
+
49
+ mq = functor
50
+ @manager.stubs(:mq).returns(mq)
51
+
52
+ mq.get_worker_version = 1
53
+
54
+ worker_queue = @worker_queue
55
+ mq.read_all_worker_statuses = lambda do |hostname|
56
+ worker_queue
57
+ end
58
+
59
+ mq.take_worker_status = lambda do |options, timeout|
60
+ worker_queue.delete_if {|w|w.process_id == options[:process_id] }.first
61
+ end
62
+
63
+ pids = @pids
64
+ hostname = @hostname
65
+ @manager.define_method(:fork) do
66
+ newpid = pids.size + 1
67
+ pids << newpid
68
+ worker_info = {
69
+ :hostname => hostname,
70
+ :process_id => newpid,
71
+ :worker_type => :task,
72
+ :worker_id => newpid,
73
+ :version => 1
74
+ }
75
+
76
+ worker_queue << Skynet::WorkerStatusMessage.new(worker_info)
77
+ newpid
78
+ end
79
+ end
80
+
81
+ def test_manager_start
82
+ setup_manager
83
+ @manager.start_workers
84
+ assert_equal 2, @manager.worker_pids.size
85
+ assert_equal @pids.sort, @manager.worker_pids.sort
86
+ assert_equal @pids.sort, @manager.worker_queue.collect {|q|q.process_id}.sort
87
+ end
88
+
89
+ def test_check_workers
90
+ setup_manager
91
+ Skynet::Manager.any_instance.expects(:worker_alive?).times(2).returns(true)
92
+ @manager.start_workers
93
+ @manager.check_workers
94
+ assert_equal 2, @manager.worker_pids.size
95
+ assert_equal @pids.sort, @manager.worker_pids.sort
96
+ assert_equal @pids.sort, @manager.worker_queue.collect {|q|q.process_id}.sort
97
+ end
98
+
99
+ def test_running_pids
100
+ setup_manager
101
+ Skynet::Manager.any_instance.expects(:worker_alive?).with(1).returns(true)
102
+ Skynet::Manager.any_instance.expects(:worker_alive?).with(2).returns(false)
103
+ @manager.start_workers
104
+ @manager.check_workers
105
+ assert_equal 1, @manager.worker_pids.size
106
+ assert_equal [1], @manager.worker_pids.sort
107
+ assert_equal [1], @manager.worker_queue.collect {|q|q.process_id}.sort
108
+ end
109
+
110
+ ## XXX FIXME. What happens if there's a worker missing from the pidfile, but was running?
111
+ def test_more_in_pidfile_than_queue_alive
112
+ setup_manager
113
+ @manager.expects(:worker_alive?).with(1).returns(false)
114
+ Skynet.configure(:SKYNET_LOG_LEVEL => 4) do
115
+ @manager.start_workers
116
+
117
+ @manager.expects(:worker_alive?).with(2).returns(true)
118
+ @worker_queue.delete_if {|w| w.process_id == 1}
119
+ @manager.check_workers
120
+ end
121
+ assert_equal 2, @manager.worker_pids.size
122
+ assert_equal [2,3], @manager.worker_pids.sort
123
+ assert_equal [2,3], @manager.worker_queue.collect {|q|q.process_id}.sort
124
+ end
125
+
126
+ def test_dead_workers
127
+ setup_manager
128
+ Skynet::Manager.any_instance.expects(:worker_alive?).times(1).with(1).returns(false)
129
+ # Skynet::Manager.any_instance.expects(:worker_alive?).with(2).returns(true)
130
+ @manager.start_workers
131
+ @manager.check_workers
132
+ assert_equal [2], @manager.worker_pids.sort
133
+ assert_equal [2], @manager.worker_queue.collect {|q|q.process_id}.sort
134
+ end
135
+
136
+
137
+ private
138
+
139
+ def mq
140
+ Skynet::MessageQueueAdapter::Mysql.new
141
+ end
142
+ end
@@ -0,0 +1,229 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class MysqlMessageQueueTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ Skynet.configure(
7
+ :ENABLE => false,
8
+ :SKYNET_LOG_FILE => STDOUT,
9
+ :SKYNET_LOG_LEVEL => Logger::ERROR
10
+ )
11
+ end
12
+
13
+ def setup_worker_message
14
+ @worker_message = Skynet::WorkerStatusMessage.new(
15
+ :tasktype => :task,
16
+ :drburi => "localhost",
17
+ :job_id => 1,
18
+ :task_id => 2,
19
+ :payload => "payload",
20
+ :payload_type => "task",
21
+ :expiry => 20,
22
+ :expire_time => 1095108406.9251,
23
+ :iteration => 0,
24
+ :name => "name",
25
+ :version => 1,
26
+ :queue_id => 0
27
+ )
28
+ end
29
+
30
+ def setup_task_message
31
+ @task_message = Skynet::Message.new(
32
+ :tasktype => :task,
33
+ :drburi => "localhost",
34
+ :job_id => 1,
35
+ :task_id => 2,
36
+ :payload => "payload",
37
+ :payload_type => "task",
38
+ :expiry => 20,
39
+ :expire_time => 0,
40
+ :iteration => 0,
41
+ :name => "name",
42
+ :version => 1,
43
+ :retry => 2,
44
+ :queue_id => 0
45
+ )
46
+ end
47
+
48
+ def test_worker_status_message
49
+ setup_worker_message
50
+ {
51
+ :queue_id => 0,
52
+ :tasksubtype => :worker,
53
+ :tasktype => :status,
54
+ :name => "name",
55
+ :hostname => nil,
56
+ :worker_id => nil,
57
+ :map_or_reduce => nil,
58
+ :process_id => nil,
59
+ :started_at => nil,
60
+ :job_id => 1,
61
+ :iteration => 0,
62
+ :processed => nil,
63
+ :task_id => 2,
64
+ :version => 1
65
+ }.each do |key, val|
66
+ assert_equal val, @worker_message.send(key), key
67
+ end
68
+ assert_equal @worker_message.to_a, Skynet::WorkerStatusMessage.new([:status, :worker, nil, nil, nil, 1, 2, 0, "name", nil, nil, 1, nil, 0]).to_a
69
+ end
70
+
71
+ def test_task_message
72
+ setup_task_message
73
+ {:payload=>"payload",
74
+ :queue_id=>0,
75
+ :tasktype=>:task,
76
+ :name=>"name",
77
+ :payload_type=>:task,
78
+ :expiry=>20,
79
+ :drburi=>"localhost",
80
+ :expire_time=>0,
81
+ :job_id=>1,
82
+ :iteration=>0,
83
+ :retry=>2,
84
+ :task_id=>2,
85
+ :version=>1}.each do |key, val|
86
+ assert_equal val, @task_message.send(key)
87
+ end
88
+ assert_equal @task_message.to_a, Skynet::Message.new([:task, "localhost", 2, 1, "payload", :task, "name", 20, 0, 0, 1, 2, 0]).to_a
89
+ end
90
+
91
+
92
+ def test_worker_status_template
93
+ template = Skynet::WorkerStatusMessage.worker_status_template(:hostname => "localhost", :process_id => $$)
94
+ [:status,:worker, nil, "localhost", :skip, nil, nil, nil, nil, nil, nil, nil, nil, nil].each_with_index do |field, ii|
95
+ next if field == :skip
96
+ assert_equal field, template[ii]
97
+ end
98
+ end
99
+
100
+ def test_fallback_message
101
+ setup_task_message
102
+ fb = @task_message.fallback_task_message
103
+ test_fb = {:payload=>"payload",
104
+ :queue_id=>0,
105
+ :tasktype=>:task,
106
+ :name=>"name",
107
+ :payload_type=>:task,
108
+ :expiry=>20,
109
+ :drburi=>"localhost",
110
+ :expire_time=>1200599892,
111
+ :job_id=>1,
112
+ :iteration=>1,
113
+ :retry=>2,
114
+ :task_id=>2,
115
+ :version=>1}
116
+
117
+ test_fb.each do |key, val|
118
+ next if key == :expire_time
119
+ assert_equal val, fb.send(key)
120
+ end
121
+
122
+ end
123
+
124
+ def test_retry
125
+ setup_task_message
126
+ test_fb = {:payload=>"payload",
127
+ :queue_id=>0,
128
+ :tasktype=>:task,
129
+ :name=>"name",
130
+ :payload_type=>:task,
131
+ :expiry=>20,
132
+ :drburi=>"localhost",
133
+ :job_id=>1,
134
+ :retry=>2,
135
+ :task_id=>2,
136
+ :version=>1}
137
+
138
+ fb1 = @task_message.fallback_task_message
139
+ test_fb.merge(:iteration => 1).each do |k,v|
140
+ assert_equal v, fb1.send(k)
141
+ end
142
+
143
+ fb2 = fb1.fallback_task_message
144
+ test_fb.merge(:iteration => 2).each do |k,v|
145
+ assert_equal v, fb2.send(k)
146
+ end
147
+
148
+ fb3 = fb2.fallback_task_message
149
+ test_fb.merge(:iteration => -1).each do |k,v|
150
+ assert_equal v, fb3.send(k)
151
+ end
152
+ end
153
+
154
+ def test_next_task_template
155
+ template = Skynet::Message.next_task_template(0,:any, 99)
156
+ [:task, nil, nil, nil, nil, :any, nil, nil, :skip, 0..6, 0, nil, 99].each_with_index do |field, ii|
157
+ next if field == :skip
158
+ assert_equal field, template[ii]
159
+ end
160
+ end
161
+
162
+ def test_result_template
163
+ template = Skynet::Message.result_template(88,:task)
164
+ [:task, nil, nil, 88, nil, nil, nil, nil, nil, nil, nil, nil, nil].each_with_index do |field, ii|
165
+ assert_equal field, template[ii]
166
+ end
167
+ end
168
+
169
+ def test_result_message
170
+ setup_task_message
171
+ result = @task_message.result_message("result")
172
+ {
173
+ :payload=>"result",
174
+ :queue_id=>0,
175
+ :tasktype=>:result,
176
+ :name=>"name",
177
+ :payload_type=>:result,
178
+ :expiry=>20,
179
+ :drburi=>"localhost",
180
+ :expire_time=>0,
181
+ :job_id=>1,
182
+ :iteration=>0,
183
+ :retry=>2,
184
+ :task_id=>2,
185
+ :version=>1
186
+ }.each do |key, val|
187
+ assert_equal val, result.send(key)
188
+ end
189
+
190
+ end
191
+
192
+ def test_fallback_template
193
+ setup_task_message
194
+ template = @task_message.fallback_template
195
+ [:task, "localhost", 2, nil, nil, nil, nil, nil, nil, 1..6, 1, nil, 0].each_with_index do |field, ii|
196
+ assert_equal field, template[ii]
197
+ end
198
+ end
199
+
200
+ def test_no_retry
201
+ setup_task_message
202
+ @task_message.retry = 0
203
+ fb1 = @task_message.fallback_task_message
204
+ {
205
+ :payload=>"payload",
206
+ :queue_id=>0,
207
+ :tasktype=>:task,
208
+ :name=>"name",
209
+ :payload_type=>:task,
210
+ :expiry=>20,
211
+ :drburi=>"localhost",
212
+ :job_id=>1,
213
+ :iteration=>-1,
214
+ :retry=>0,
215
+ :task_id=>2,
216
+ :version=>1
217
+ }.each do |k,v|
218
+ assert_equal v, fb1.send(k)
219
+ end
220
+ end
221
+
222
+ def test_payload
223
+ setup_task_message
224
+ @task_message.payload = "hi"
225
+ assert_equal YAML::dump("hi"), @task_message.raw_payload
226
+ end
227
+
228
+
229
+ end
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class SkynetTaskTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ Skynet.configure(
7
+ :ENABLE => false,
8
+ :SKYNET_LOG_FILE => STDOUT,
9
+ :SKYNET_LOG_LEVEL => Logger::ERROR
10
+ )
11
+ end
12
+
13
+ def test_master_task
14
+ job = Skynet::Job.new(:map_reduce_class => self.class, :async => true)
15
+ master_task = Skynet::Task.master_task(job)
16
+ master_job = Skynet::Job.new(master_task.process)
17
+ assert_equal self.class.to_s, master_job.map
18
+ assert ! master_job.async
19
+ assert_equal true, master_job.local_master
20
+ end
21
+
22
+ def self.map(datas)
23
+ end
24
+ end
@@ -1,41 +1,36 @@
1
- ENV["RAILS_ENV"] = "test"
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
2
 
3
- require 'test/unit'
4
- require 'pp'
5
- require '../lib/skynet.rb'
6
-
7
-
8
- # Tests for the partitioners.
9
- #
10
3
  class TuplespaceMessageQueueTest < Test::Unit::TestCase
11
4
 
12
5
  def setup
13
6
  Skynet.configure(
14
- :ENABLE => false,
15
- # :SKYNET_PIDS_FILE => File.expand_path("#{RAILS_ROOT}/log/skynet_#{RAILS_ENV}.pids"),
16
- :SKYNET_LOG_FILE => STDOUT,
17
- :SKYNET_LOG_LEVEL => Logger::ERROR,
18
- :SKYNET_LOCAL_MANAGER_URL => "druby://localhost:40000",
19
- :MESSAGE_QUEUE_ADAPTER => "Skynet::MessageQueueAdapter::TupleSpace",
20
- :TUPLESPACE_DRBURIS => ["druby://localhost:77647"],
21
- :USE_RINGSERVER => false
7
+ :ENABLE => false,
8
+ # :SKYNET_PIDS_FILE => File.expand_path("#{RAILS_ROOT}/log/skynet_#{RAILS_ENV}.pids"),
9
+ :SKYNET_LOG_FILE => STDOUT,
10
+ :SKYNET_LOG_LEVEL => Logger::ERROR,
11
+ :SKYNET_LOCAL_MANAGER_URL => "druby://localhost:40000",
12
+ :MESSAGE_QUEUE_ADAPTER => "Skynet::MessageQueueAdapter::TupleSpace",
13
+ :TS_DRBURIS => ["druby://localhost:77647"],
14
+ :TS_USE_RINGSERVER => false
22
15
  )
23
16
  @ts ||= Rinda::TupleSpace.new
24
- @@tss ||= DRb.start_service(Skynet::CONFIG[:TUPLESPACE_DRBURIS].first, @ts)
17
+ @@tss ||= DRb.start_service(Skynet::CONFIG[:TS_DRBURIS].first, @ts)
25
18
  mq.clear_outstanding_tasks
26
19
 
27
20
  @worker_message = Skynet::Message.new(
28
- :tasktype=> :task,
29
- :drburi=> "localhost",
30
- :job_id => 1,
31
- :task_id => 2,
32
- :payload => "task",
21
+ :tasktype => :task,
22
+ :drburi => "localhost",
23
+ :job_id => 1,
24
+ :task_id => 2,
25
+ :payload => "task",
33
26
  :payload_type => "master",
34
- :expiry => 20,
35
- :expire_time => 0,
36
- :iteration => 0,
37
- :name => "test",
38
- :version => 1
27
+ :expiry => 20,
28
+ :expire_time => 0,
29
+ :iteration => 0,
30
+ :name => "test",
31
+ :version => 1,
32
+ :retry => 3,
33
+ :queue_id => 0
39
34
  )
40
35
 
41
36
  end
@@ -44,7 +39,7 @@ class TuplespaceMessageQueueTest < Test::Unit::TestCase
44
39
  @ts.write([:test])
45
40
  assert_equal [:test], @ts.take([:test])
46
41
 
47
- rts = DRbObject.new(nil, Skynet::CONFIG[:TUPLESPACE_DRBURIS].first)
42
+ rts = DRbObject.new(nil, Skynet::CONFIG[:TS_DRBURIS].first)
48
43
  rts.write([:test])
49
44
  assert_equal [:test], rts.take([:test])
50
45
  end
@@ -84,8 +79,8 @@ class TuplespaceMessageQueueTest < Test::Unit::TestCase
84
79
  message.expiry=0.4
85
80
  assert mq.write_message(message)
86
81
  assert_equal message.to_a, mq.take_next_task(1).to_a
87
- sleep 0.6
88
- ntt = Skynet::Message.next_task_template(1)
82
+ sleep 1
83
+ ntt = Skynet::Message.next_task_template(1,nil,0)
89
84
  assert_equal 2, mq.take_next_task(1,0.00001).task_id
90
85
  end
91
86