skynet 0.9.1 → 0.9.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/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
|