skynet 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +99 -0
- data/Manifest.txt +10 -9
- data/README.txt +74 -7
- data/app_generators/skynet_install/skynet_install_generator.rb +26 -22
- data/app_generators/skynet_install/templates/migration.rb +11 -5
- data/app_generators/skynet_install/templates/skynet +25 -12
- data/app_generators/skynet_install/templates/skynet_schema.sql +56 -0
- data/bin/skynet +26 -2
- data/bin/skynet_install +24 -0
- data/bin/skynet_tuplespace_server +13 -0
- data/config/hoe.rb +1 -0
- data/lib/skynet.rb +3 -0
- data/lib/skynet/mapreduce_helper.rb +74 -0
- data/lib/skynet/message_queue_adapters/mysql.rb +225 -172
- data/lib/skynet/message_queue_adapters/tuple_space.rb +31 -16
- data/lib/skynet/skynet_active_record_extensions.rb +78 -46
- data/lib/skynet/skynet_config.rb +162 -23
- data/lib/skynet/skynet_console.rb +23 -10
- data/lib/skynet/skynet_console_helper.rb +61 -58
- data/lib/skynet/skynet_job.rb +741 -493
- data/lib/skynet/skynet_launcher.rb +5 -1
- data/lib/skynet/skynet_manager.rb +106 -49
- data/lib/skynet/skynet_message.rb +169 -174
- data/lib/skynet/skynet_message_queue.rb +29 -16
- data/lib/skynet/skynet_partitioners.rb +92 -0
- data/lib/skynet/skynet_ruby_extensions.rb +3 -4
- data/lib/skynet/skynet_task.rb +61 -19
- data/lib/skynet/skynet_tuplespace_server.rb +0 -2
- data/lib/skynet/skynet_worker.rb +73 -51
- data/lib/skynet/version.rb +1 -1
- data/test/test_active_record_extensions.rb +138 -0
- data/test/test_helper.rb +6 -0
- data/test/{mysql_message_queue_adaptor_test.rb → test_mysql_message_queue_adapter.rb} +94 -30
- data/test/test_skynet.rb +11 -11
- data/test/test_skynet_install_generator.rb +0 -4
- data/test/test_skynet_job.rb +717 -0
- data/test/test_skynet_manager.rb +142 -0
- data/test/test_skynet_message.rb +229 -0
- data/test/test_skynet_task.rb +24 -0
- data/test/{tuplespace_message_queue_test.rb → test_tuplespace_message_queue.rb} +25 -30
- data/website/index.html +56 -16
- data/website/index.txt +55 -25
- data/website/template.rhtml +1 -1
- metadata +29 -13
- data/app_generators/skynet_install/templates/skynet_console +0 -16
- data/bin/skynet_console +0 -9
- data/sometest.rb +0 -23
- data/test/all_models_test.rb +0 -139
- data/test/skynet_manager_test.rb +0 -107
- data/test/skynet_message_test.rb +0 -42
- data/tmtags +0 -1242
@@ -43,18 +43,20 @@ class Skynet
|
|
43
43
|
@ts = ts
|
44
44
|
end
|
45
45
|
|
46
|
-
def take_next_task(curver,timeout=nil,payload_type=nil)
|
47
|
-
message = Skynet::Message.new(take(Skynet::Message.next_task_template(curver,payload_type),timeout))
|
46
|
+
def take_next_task(curver,timeout=nil,payload_type=nil,queue_id=0)
|
47
|
+
message = Skynet::Message.new(take(Skynet::Message.next_task_template(curver,payload_type, queue_id),timeout))
|
48
48
|
write_fallback_task(message)
|
49
49
|
message
|
50
50
|
end
|
51
51
|
|
52
52
|
def write_message(message,timeout=nil)
|
53
|
+
timeout ||= message.expiry
|
53
54
|
write(message,timeout)
|
54
55
|
end
|
55
56
|
|
56
57
|
def write_result(message,result=[],timeout=nil)
|
57
58
|
result_message = message.result_message(result).to_a
|
59
|
+
timeout ||= result_message.expiry
|
58
60
|
write(result_message,timeout)
|
59
61
|
take_fallback_message(message)
|
60
62
|
result_message
|
@@ -65,6 +67,7 @@ class Skynet
|
|
65
67
|
end
|
66
68
|
|
67
69
|
def write_error(message,error='',timeout=nil)
|
70
|
+
timeout ||= message.expiry
|
68
71
|
write(message.error_message(error),timeout)
|
69
72
|
take_fallback_message(message)
|
70
73
|
end
|
@@ -99,14 +102,25 @@ class Skynet
|
|
99
102
|
cnt
|
100
103
|
end
|
101
104
|
|
102
|
-
def list_tasks(iteration=nil)
|
103
|
-
read_all(Skynet::Message.outstanding_tasks_template(iteration))
|
105
|
+
def list_tasks(iteration=nil,queue_id=0)
|
106
|
+
read_all(Skynet::Message.outstanding_tasks_template(iteration,queue_id))
|
104
107
|
end
|
105
108
|
|
106
109
|
def list_results
|
107
110
|
read_all(Skynet::Message.outstanding_results_template)
|
108
111
|
end
|
109
112
|
|
113
|
+
def version_active?(curver=nil, queue_id= 0)
|
114
|
+
return true unless curver
|
115
|
+
begin
|
116
|
+
message_row = read(Skynet::Message.next_task_template(curver, nil, queue_id),0.00001)
|
117
|
+
true
|
118
|
+
rescue Skynet::RequestExpiredError
|
119
|
+
return true if curver.to_i == get_worker_version.to_i
|
120
|
+
false
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
110
124
|
def get_worker_version
|
111
125
|
begin
|
112
126
|
message = Skynet::WorkerVersionMessage.new(read(Skynet::WorkerVersionMessage.template,0.00001))
|
@@ -198,22 +212,23 @@ class Skynet
|
|
198
212
|
###### FALLBACK METHODS
|
199
213
|
def write_fallback_task(message)
|
200
214
|
return unless USE_FALLBACK_TASKS
|
201
|
-
debug "4 WRITING BACKUP TASK #{message.task_id}",
|
215
|
+
debug "4 WRITING BACKUP TASK #{message.task_id}", message.to_h
|
202
216
|
ftm = message.fallback_task_message
|
203
|
-
debug "WRITE FALLBACK TASK", ftm.
|
217
|
+
debug "WRITE FALLBACK TASK", ftm.to_h
|
204
218
|
timeout = message.expiry * 8
|
205
|
-
write(ftm,timeout)
|
219
|
+
write(ftm,timeout) unless ftm.iteration == -1
|
206
220
|
ftm
|
207
221
|
end
|
208
222
|
|
209
223
|
def take_fallback_message(message,timeout=0.01)
|
210
224
|
return unless USE_FALLBACK_TASKS
|
225
|
+
return if message.retry <= message.iteration
|
211
226
|
begin
|
212
227
|
# debug "LOOKING FOR FALLBACK TEMPLATE", message.fallback_template
|
213
228
|
fb_message = Skynet::Message.new(take(message.fallback_template,timeout))
|
214
229
|
# debug "TOOK FALLBACK MESSAGE for TASKID: #{fb_message.task_id}"
|
215
230
|
rescue Skynet::RequestExpiredError => e
|
216
|
-
error "Couldn't find expected FALLBACK MESSAGE"
|
231
|
+
error "Couldn't find expected FALLBACK MESSAGE", Skynet::Message.new(message.fallback_template).to_h
|
217
232
|
end
|
218
233
|
end
|
219
234
|
## END FALLBACK METHODS
|
@@ -267,28 +282,28 @@ class Skynet
|
|
267
282
|
loop do
|
268
283
|
begin
|
269
284
|
DRb.start_service
|
270
|
-
if Skynet::CONFIG[:
|
271
|
-
Skynet::CONFIG[:
|
285
|
+
if Skynet::CONFIG[:TS_USE_RINGSERVER]
|
286
|
+
Skynet::CONFIG[:TS_SERVER_HOSTS][@@curhostidx] =~ /(.+):(\d+)/
|
272
287
|
host = $1
|
273
288
|
port = $2.to_i
|
274
289
|
@@ts = connect_to_tuple_space(host,port)
|
275
290
|
else
|
276
|
-
drburi = Skynet::CONFIG[:
|
291
|
+
drburi = Skynet::CONFIG[:TS_DRBURIS].first
|
277
292
|
drburi = "druby://#{drburi}" unless drburi =~ %r{druby://}
|
278
293
|
@@ts = get_tuple_space_from_drburi(drburi)
|
279
294
|
log.info "#{self} CONNECTED TO #{drburi}"
|
280
295
|
end
|
281
296
|
return @@ts
|
282
297
|
rescue RuntimeError => e
|
283
|
-
if Skynet::CONFIG[:
|
284
|
-
log.error "#{self} Couldn't connect to #{Skynet::CONFIG[:
|
298
|
+
if Skynet::CONFIG[:TS_SERVER_HOSTS][@@curhostidx + 1]
|
299
|
+
log.error "#{self} Couldn't connect to #{Skynet::CONFIG[:TS_SERVER_HOSTS][@@curhostidx]} trying #{Skynet::CONFIG[:TS_SERVER_HOSTS][@@curhostidx+1]}"
|
285
300
|
@@curhostidx += 1
|
286
301
|
next
|
287
302
|
else
|
288
|
-
raise Skynet::ConnectionError.new("Can't find ring finger @ #{Skynet::CONFIG[:
|
303
|
+
raise Skynet::ConnectionError.new("Can't find ring finger @ #{Skynet::CONFIG[:TS_SERVER_HOSTS][@@curhostidx]}. #{e.class} #{e.message}")
|
289
304
|
end
|
290
305
|
rescue Exception => e
|
291
|
-
raise Skynet::ConnectionError.new("Error getting tuplespace @ #{Skynet::CONFIG[:
|
306
|
+
raise Skynet::ConnectionError.new("Error getting tuplespace @ #{Skynet::CONFIG[:TS_SERVER_HOSTS][@@curhostidx]}. #{e.class} #{e.message}")
|
292
307
|
end
|
293
308
|
end
|
294
309
|
return @@ts
|
@@ -296,7 +311,7 @@ class Skynet
|
|
296
311
|
|
297
312
|
def self.connect_to_tuple_space(host,port)
|
298
313
|
log.info "#{self} trying to connect to #{host}:#{port}"
|
299
|
-
if Skynet::CONFIG[:
|
314
|
+
if Skynet::CONFIG[:TS_USE_RINGSERVER]
|
300
315
|
ring_finger = Rinda::RingFinger.new(host,port)
|
301
316
|
ring_server = ring_finger.lookup_ring_any(0.5)
|
302
317
|
|
@@ -11,18 +11,20 @@ class ActiveRecord::Base
|
|
11
11
|
|
12
12
|
jobopts = {
|
13
13
|
:single => true,
|
14
|
-
:
|
14
|
+
:mappers => 1,
|
15
15
|
:map_data => [data],
|
16
16
|
:name => "send_later #{self.class}##{method}",
|
17
17
|
:map_name => "",
|
18
|
-
:map_timeout =>
|
19
|
-
:reduce_timeout =>
|
20
|
-
:master_timeout =>
|
18
|
+
:map_timeout => 60,
|
19
|
+
:reduce_timeout => 60,
|
20
|
+
:master_timeout => 60,
|
21
21
|
:master_result_timeout => 1.minute,
|
22
|
-
:map_reduce_class => Skynet::ActiveRecordAsync
|
22
|
+
:map_reduce_class => Skynet::ActiveRecordAsync,
|
23
|
+
:master_retry => 0,
|
24
|
+
:map_retry => 0
|
23
25
|
}
|
24
26
|
job = Skynet::AsyncJob.new(jobopts)
|
25
|
-
job.
|
27
|
+
job.run
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
@@ -60,7 +62,7 @@ module ActiveRecord
|
|
60
62
|
|
61
63
|
class Mapreduce
|
62
64
|
BATCH_SIZE=1000 unless defined?(BATCH_SIZE)
|
63
|
-
|
65
|
+
MAX_BATCHES_PER_JOB = 1000 unless defined?(MAX_BATCHES_PER_JOB)
|
64
66
|
attr_accessor :find_args, :batch_size
|
65
67
|
attr_reader :model_class
|
66
68
|
|
@@ -85,11 +87,17 @@ module ActiveRecord
|
|
85
87
|
end
|
86
88
|
new(:find_args => args, :batch_size => args.delete(:batch_size), :model_class => args.delete(:model_class))
|
87
89
|
end
|
90
|
+
|
91
|
+
def log
|
92
|
+
Skynet::Logger.get
|
93
|
+
end
|
88
94
|
|
89
95
|
def each_range(opts={})
|
90
96
|
opts = opts.clone
|
91
97
|
opts[:id] || opts[:id] = 0
|
92
98
|
rows = chunk_query(opts)
|
99
|
+
# log.error "ROWS, #{rows.pretty_print_inspect}"
|
100
|
+
|
93
101
|
|
94
102
|
ii = 0
|
95
103
|
if rows.empty?
|
@@ -133,48 +141,60 @@ module ActiveRecord
|
|
133
141
|
# select (@t2:=(@t2+1) % 2) as evenodd, ((@t3:=@t4)+1) as first, @t4:=id as last from profiles where ((@t1:=(@t1+1) % 1000)=0) order by id LIMIT 100;
|
134
142
|
|
135
143
|
mc.connection.execute('select @t1:=0, @t2:=-1, @t3:=0, @t4:=0')
|
136
|
-
|
144
|
+
sql = "select @t2:=(@t2+1) as cnt, ((@t3:=@t4)+1) as first, @t4:=#{table_name}.id as last from #{table_name} #{opts[:joins]} where #{opts[:conditions]} ORDER BY #{table_name}.id #{limit}"
|
145
|
+
# log.error "SQL #{sql}"
|
146
|
+
mc.connection.select_all(sql)
|
137
147
|
|
138
148
|
# mc.connection.select_values(mc.send(:construct_finder_sql, :select => "#{mc.table_name}.id", :joins => opts[:joins], :conditions => conditions, :limit => opts[:limit], :order => :id))
|
139
149
|
end
|
140
150
|
|
151
|
+
def run_job_for_batch(batches,&block)
|
152
|
+
jobopts = {
|
153
|
+
:mappers => 20000,
|
154
|
+
:map_data => batches,
|
155
|
+
:name => "each #{model_class} MASTER",
|
156
|
+
:map_name => "each #{model_class} MAP",
|
157
|
+
:map_timeout => 60,
|
158
|
+
:master_timeout => 12.hours,
|
159
|
+
:master_result_timeout => 60,
|
160
|
+
:master_retry => 0,
|
161
|
+
:map_retry => 0
|
162
|
+
}
|
163
|
+
|
164
|
+
job = nil
|
165
|
+
if block_given?
|
166
|
+
job = Skynet::Job.new(jobopts.merge(:map => block), :local_master => true)
|
167
|
+
else
|
168
|
+
job = Skynet::AsyncJob.new(jobopts.merge(:map_reduce_class => "#{self.class}"))
|
169
|
+
end
|
170
|
+
job.run
|
171
|
+
end
|
141
172
|
|
142
173
|
def each(klass_or_method=nil,&block)
|
143
174
|
klass_or_method ||= model_class
|
144
|
-
|
175
|
+
log = Skynet::Logger.get
|
176
|
+
|
177
|
+
batches = []
|
145
178
|
each_range(find_args) do |ids,ii|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
]
|
179
|
+
batch_item = [
|
180
|
+
ids['first'].to_i,
|
181
|
+
ids['last'].to_i,
|
182
|
+
find_args.clone,
|
183
|
+
model_class
|
184
|
+
]
|
153
185
|
if block_given?
|
154
|
-
|
186
|
+
batch_item << block
|
155
187
|
else
|
156
|
-
|
188
|
+
batch_item << "#{klass_or_method}"
|
189
|
+
end
|
190
|
+
batches << batch_item
|
191
|
+
if batches.size >= MAX_BATCHES_PER_JOB
|
192
|
+
log.error "MAX BATCH SIZE EXCEEDED RUNNING: #{batches.size}"
|
193
|
+
run_job_for_batch(batches)
|
194
|
+
batches = []
|
157
195
|
end
|
158
196
|
end
|
159
|
-
|
160
|
-
job = nil
|
161
|
-
jobopts = {
|
162
|
-
:map_tasks => 20000,
|
163
|
-
:map_data => batches,
|
164
|
-
:name => "each #{model_class} MASTER",
|
165
|
-
:map_name => "each #{model_class} MAP",
|
166
|
-
:map_timeout => 1.hour,
|
167
|
-
:reduce_timeout => 1.hour,
|
168
|
-
:master_timeout => 8.hours,
|
169
|
-
:master_result_timeout => 1.minute
|
170
|
-
|
171
|
-
}
|
172
|
-
if block_given?
|
173
|
-
job = Skynet::Job.new(jobopts.merge(:map_reduce_class => "#{self.class}"))
|
174
|
-
else
|
175
|
-
job = Skynet::AsyncJob.new(jobopts.merge(:map_reduce_class => "#{self.class}"))
|
176
|
-
end
|
177
|
-
job.run
|
197
|
+
run_job_for_batch(batches)
|
178
198
|
end
|
179
199
|
|
180
200
|
alias_method :mapreduce, :each
|
@@ -194,28 +214,40 @@ module ActiveRecord
|
|
194
214
|
end
|
195
215
|
|
196
216
|
def self.map(datas)
|
217
|
+
return unless datas and not datas.empty?
|
197
218
|
datas.each do |data|
|
219
|
+
next if (not data.is_a?(Array))
|
220
|
+
next if data.empty?
|
198
221
|
model_class = data[3].constantize
|
199
222
|
table_name = model_class.table_name
|
200
223
|
conditions = "#{table_name}.id >= #{data[0]}"
|
201
224
|
conditions += " AND #{table_name}.id <= #{data[1]}" if data[1] > data[0]
|
202
225
|
conditions = "(#{conditions})"
|
203
226
|
# conditions = "ID BETWEEN #{data[0]} and #{data[1]}"
|
204
|
-
if
|
227
|
+
if not data[2]
|
205
228
|
data[2] = {:conditions => conditions}
|
206
|
-
|
229
|
+
elsif data[2].is_a?(Hash) and data[2].empty?
|
230
|
+
data[2] = {:conditions => conditions}
|
231
|
+
elsif data[2].is_a?(Hash) and (not data[2][:conditions] or data[2][:conditions].empty?)
|
232
|
+
data[2][:conditions] = conditions
|
233
|
+
else
|
207
234
|
data[2][:conditions] += " AND #{conditions}"
|
208
235
|
end
|
209
236
|
data[2][:select] = "#{table_name}.*"
|
210
|
-
|
237
|
+
|
238
|
+
# log.error "GETTING #{data.pretty_print_inspect}"
|
239
|
+
models = model_class.find(:all, data[2])
|
240
|
+
# log.error "GOT MODELS: #{models.size}"
|
241
|
+
models.each do |ar_object|
|
211
242
|
begin
|
212
243
|
if data[4].kind_of?(String)
|
213
|
-
|
214
|
-
data[4].
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
244
|
+
if ar_object.respond_to?(data[4].to_sym)
|
245
|
+
# log.error "CALLING #{data[4]} on #{ar_object.class}:#{ar_object.id}"
|
246
|
+
ar_object.send(data[4].to_sym)
|
247
|
+
else
|
248
|
+
begin
|
249
|
+
data[4].constantize.each(ar_object)
|
250
|
+
rescue NameError
|
219
251
|
raise NameError.new("#{data[4]} is not a class or an instance method in #{model_class}")
|
220
252
|
end
|
221
253
|
end
|
data/lib/skynet/skynet_config.rb
CHANGED
@@ -2,33 +2,60 @@ class Skynet
|
|
2
2
|
LOGDIR = "/var/log"
|
3
3
|
|
4
4
|
CONFIG = {
|
5
|
-
:ENABLE
|
6
|
-
:SOLO
|
7
|
-
:SKYNET_LOG_DIR
|
8
|
-
:SKYNET_PID_DIR
|
9
|
-
:SKYNET_PIDS_FILE
|
10
|
-
:SKYNET_LOG_FILE
|
11
|
-
:SKYNET_LOG_LEVEL
|
12
|
-
:SKYNET_LOCAL_MANAGER_URL
|
13
|
-
:MESSAGE_QUEUE_ADAPTER
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
|
24
|
-
:
|
25
|
-
:
|
5
|
+
:ENABLE => true,
|
6
|
+
:SOLO => false,
|
7
|
+
:SKYNET_LOG_DIR => LOGDIR,
|
8
|
+
:SKYNET_PID_DIR => "/tmp",
|
9
|
+
:SKYNET_PIDS_FILE => "/tmp/skynet.pid",
|
10
|
+
:SKYNET_LOG_FILE => STDOUT,
|
11
|
+
:SKYNET_LOG_LEVEL => Logger::ERROR,
|
12
|
+
:SKYNET_LOCAL_MANAGER_URL => "druby://localhost:40000",
|
13
|
+
:MESSAGE_QUEUE_ADAPTER => ("Skynet::MessageQueueAdapter::TupleSpace" || "Skynet::MessageQueueAdapter::Mysql"),
|
14
|
+
:TS_USE_RINGSERVER => true,
|
15
|
+
:TS_DRBURIS => ["druby://localhost:47647"], # If you do not use RINGSERVER, you must specifiy the DRBURI
|
16
|
+
:TS_SERVER_HOSTS => ["localhost:7647"],
|
17
|
+
:TS_SERVER_START_DELAY => 10,
|
18
|
+
# :MYSQL_QUEUE_DATABASE => "skynet_queue",
|
19
|
+
:MYSQL_TEMPERATURE_CHANGE_SLEEP => 40,
|
20
|
+
:MYSQL_MESSAGE_QUEUE_TAPLE => "skynet_message_queues",
|
21
|
+
:MYSQL_MESSAGE_QUEUE_TEMP_CHECK_DELAY => 40,
|
22
|
+
:MYSQL_NEXT_TASK_TIMEOUT => 60,
|
23
|
+
:MYSQL_ADAPTER => "mysql",
|
24
|
+
:MYSQL_HOST => "localhost",
|
25
|
+
:MYSQL_DATABASE => "skynet",
|
26
|
+
:MYSQL_USERNAME => "root",
|
27
|
+
:MYSQL_PASSWORD => "",
|
28
|
+
:NUMBER_OF_WORKERS => 4,
|
29
|
+
:WORKER_CHECK_DELAY => 40,
|
30
|
+
:WORKER_MAX_MEMORY => 500,
|
31
|
+
:WORKER_MAX_PROCESSED => 1000,
|
32
|
+
:WORKER_VERSION_CHECK_DELAY => 30,
|
33
|
+
# :GUID_GENERATOR => nil,
|
34
|
+
:PERCENTAGE_OF_TASK_ONLY_WORKERS => 0.7,
|
35
|
+
:PERCENTAGE_OF_MASTER_ONLY_WORKERS => 0.2,
|
36
|
+
:MAX_RETRIES => 6,
|
37
|
+
:DEFAULT_MASTER_RETRY => 0,
|
38
|
+
:DEFAULT_MAP_RETRY => 3,
|
39
|
+
:DEFAULT_REDUCE_RETRY => 3,
|
40
|
+
:DEFAULT_KEEP_MAP_TASKS => 1,
|
41
|
+
:DEFAULT_KEEP_REDUCE_TASKS => 1,
|
42
|
+
:MESSAGE_QUEUES => ['first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'eighth', 'nineth']
|
26
43
|
} unless defined?(CONFIG)
|
27
|
-
|
44
|
+
|
45
|
+
def self.silent
|
46
|
+
if block_given?
|
47
|
+
Skynet.configure(:SKYNET_LOG_LEVEL => 10) do
|
48
|
+
yield
|
49
|
+
end
|
50
|
+
else
|
51
|
+
raise Error.new("Please provide a block to Skynet.silent")
|
52
|
+
end
|
53
|
+
end
|
28
54
|
|
29
55
|
def self.configure(config={})
|
30
56
|
old_config = CONFIG.dup
|
31
57
|
config.each {|k,v| CONFIG[k] = v}
|
58
|
+
Skynet::Logger.log = nil
|
32
59
|
if block_given?
|
33
60
|
ret = yield
|
34
61
|
CONFIG.keys.each do |key|
|
@@ -56,4 +83,116 @@ class Skynet
|
|
56
83
|
end
|
57
84
|
return result
|
58
85
|
end
|
59
|
-
|
86
|
+
|
87
|
+
# Skynet has many global configuration options.
|
88
|
+
# You can access specific options via Skynet::CONFIG[:OPTION] = ?
|
89
|
+
# You can set many options via
|
90
|
+
#
|
91
|
+
# Skynet.configure(:OPTION => option, :ANOTHEROPTION => anotheroption)
|
92
|
+
#
|
93
|
+
# If you want specific configuration to only apply to a block of code you can pass configure a block
|
94
|
+
#
|
95
|
+
# Skynet.configure(:SOMEOPTION => 'value') do
|
96
|
+
# run code here
|
97
|
+
# end
|
98
|
+
#
|
99
|
+
# Config Options and current defaults:
|
100
|
+
# Skynet.configure(
|
101
|
+
# :ENABLE => true,
|
102
|
+
# :SOLO => false,
|
103
|
+
# :SKYNET_LOG_DIR => LOGDIR,
|
104
|
+
# :SKYNET_PID_DIR => "/tmp",
|
105
|
+
# :SKYNET_PIDS_FILE => "/tmp/skynet.pid",
|
106
|
+
# :SKYNET_LOG_FILE => STDOUT,
|
107
|
+
# :SKYNET_LOG_LEVEL => Logger::ERROR,
|
108
|
+
# :SKYNET_LOCAL_MANAGER_URL => "druby://localhost:40000",
|
109
|
+
# :MESSAGE_QUEUE_ADAPTER => "Skynet::MessageQueueAdapter::TupleSpace",
|
110
|
+
# :TS_DRBURIS => ["druby://localhost:47647"]
|
111
|
+
# :TS_USE_RINGSERVER => true,
|
112
|
+
# :TS_SERVER_HOSTS => ["localhost:7647"],
|
113
|
+
# :TS_SERVER_START_DELAY => 10,
|
114
|
+
# :MYSQL_QUEUE_DATABASE => "skynet_queue",
|
115
|
+
# :MYSQL_TEMPERATURE_CHANGE_SLEEP => 40,
|
116
|
+
# :MYSQL_QUEUE_TEMP_POW => 0.6,
|
117
|
+
# :MYSQL_MESSAGE_QUEUE_TAPLE => "skynet_message_queues",
|
118
|
+
# :MYSQL_MESSAGE_QUEUE_TEMP_CHECK_DELAY => 40,
|
119
|
+
# :MYSQL_NEXT_TASK_TIMEOUT => 60,
|
120
|
+
# :WORKER_CHECK_DELAY => 40,
|
121
|
+
# :GUID_GENERATOR => nil,
|
122
|
+
# :NUMBER_OF_WORKERS => 4,
|
123
|
+
# :PERCENTAGE_OF_TASK_ONLY_WORKERS => 0.7,
|
124
|
+
# :PERCENTAGE_OF_MASTER_ONLY_WORKERS => 0.2,
|
125
|
+
# :MAX_RETRIES => 6,
|
126
|
+
# :DEFAULT_MASTER_RETRY => 0,
|
127
|
+
# :DEFAULT_MAP_RETRY => 3,
|
128
|
+
# :DEFAULT_REDUCE_RETRY => 3
|
129
|
+
# :KEEP_MAP_TASKS => false,
|
130
|
+
# :KEEP_REDUCE_TASKS => false
|
131
|
+
# )
|
132
|
+
#
|
133
|
+
# ENABLE turns Skynet on or off.
|
134
|
+
#
|
135
|
+
# SOLO turns on SOLO mode where Skynet can run in the current process without workers.
|
136
|
+
# Its almost a Skynet emulation mode
|
137
|
+
#
|
138
|
+
# MESSAGE_QUEUE_ADAPTER
|
139
|
+
# Skynet comes with 2 message queue adaptors
|
140
|
+
# Skynet::MessageQueueAdapter::TupleSpace
|
141
|
+
# Skynet::MessageQueueAdapter::Mysql
|
142
|
+
# The default is TupleSpace which is an in memory database.
|
143
|
+
# The mysql MQ takes running a migration that comes with skynet_install
|
144
|
+
#
|
145
|
+
# The following only apply to the TupleSpace adapter
|
146
|
+
# :TS_DRBURIS => ["druby://localhost:47647"]
|
147
|
+
# :TS_USE_RINGSERVER => true,
|
148
|
+
# :TS_SERVER_HOSTS => ["localhost:7647"],
|
149
|
+
#
|
150
|
+
# The following only apply to the Mysql adapter
|
151
|
+
# :MYSQL_QUEUE_DATABASE => "skynet_queue",
|
152
|
+
# :MYSQL_TEMPERATURE_CHANGE_SLEEP => 40,
|
153
|
+
# :MYSQL_QUEUE_TEMP_POW => 0.6,
|
154
|
+
# :MYSQL_MESSAGE_QUEUE_TAPLE => "skynet_message_queues",
|
155
|
+
# :MYSQL_MESSAGE_QUEUE_TEMP_CHECK_DELAY => 40,
|
156
|
+
# :MYSQL_NEXT_TASK_TIMEOUT => 60,
|
157
|
+
|
158
|
+
class Config
|
159
|
+
include Enumerable
|
160
|
+
|
161
|
+
def each
|
162
|
+
Skynet::CONFIG.each {|k,v| yield k,v}
|
163
|
+
end
|
164
|
+
|
165
|
+
def add_message_queue(queue_name)
|
166
|
+
self.message_queues << queue_name
|
167
|
+
end
|
168
|
+
|
169
|
+
def queue_id_by_name(queue_name)
|
170
|
+
if Skynet::CONFIG[:MESSAGE_QUEUES].index(queue_name)
|
171
|
+
return Skynet::CONFIG[:MESSAGE_QUEUES].index(queue_name)
|
172
|
+
else
|
173
|
+
raise Skynet::Error("#{queue_name} is not a valid queue")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def queue_name_by_id(queue_id)
|
178
|
+
queue_id = queue_id.to_i
|
179
|
+
if Skynet::CONFIG[:MESSAGE_QUEUES][queue_id]
|
180
|
+
return Skynet::CONFIG[:MESSAGE_QUEUES][queue_id]
|
181
|
+
else
|
182
|
+
raise Skynet::Error("#{queue_id} is not a valid queue_id")
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
|
188
|
+
def method_missing(name, *args)
|
189
|
+
name = name.to_s.upcase.to_sym
|
190
|
+
if name.to_s =~ /^(.*)=$/
|
191
|
+
name = $1.to_sym
|
192
|
+
Skynet::CONFIG[name] = args.first
|
193
|
+
else
|
194
|
+
Skynet::CONFIG[name]
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|