archipelago 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +3 -3
- data/lib/archipelago/current.rb +69 -0
- data/lib/archipelago/disco.rb +102 -29
- data/lib/archipelago/hashish.rb +72 -9
- data/lib/archipelago/pirate.rb +54 -16
- data/lib/archipelago/treasure.rb +72 -48
- data/{scripts → script}/chest.rb +6 -5
- data/{scripts → script}/console +0 -0
- data/script/overloads.rb +61 -0
- data/script/pirate.rb +7 -0
- data/script/services.rb +24 -0
- data/{scripts → script}/tranny.rb +6 -5
- data/tests/current_benchmark.rb +28 -0
- data/tests/current_test.rb +29 -0
- data/tests/disco_benchmark.rb +21 -0
- data/tests/evaltest +3 -0
- data/tests/evaltestmore +3 -0
- data/tests/pirate_test.rb +17 -3
- data/tests/test_helper.rb +12 -12
- data/tests/treasure_benchmark.rb +85 -0
- data/tests/treasure_test.rb +31 -1
- metadata +19 -11
- data/profiles/1000xChest#join!-prepare!-commit!.rb +0 -19
- data/profiles/1000xDubloon#[]=(t).rb +0 -19
- data/profiles/1000xDubloon#method_missing(t).rb +0 -21
- data/profiles/README +0 -3
- data/profiles/profile_helper.rb +0 -25
- data/scripts/pirate.rb +0 -19
data/README
CHANGED
@@ -20,15 +20,15 @@ placed within the pkg/ directory.
|
|
20
20
|
|
21
21
|
To set up an Archipelago::Tranny::Manager do the following (from scripts/tranny.rb):
|
22
22
|
|
23
|
-
:include:
|
23
|
+
:include:script/tranny.rb
|
24
24
|
|
25
25
|
To set up an Archipelago::Treasure::Chest do the following (from scripts/chest.rb):
|
26
26
|
|
27
|
-
:include:
|
27
|
+
:include:script/chest.rb
|
28
28
|
|
29
29
|
To set up an Archipelago::Pirate::Captain do the following (from scripts/pirate.rb):
|
30
30
|
|
31
|
-
:include:
|
31
|
+
:include:script/pirate.rb
|
32
32
|
|
33
33
|
To set up a test environment to play around with, run the following
|
34
34
|
commands in a few terminals:
|
data/lib/archipelago/current.rb
CHANGED
@@ -33,6 +33,75 @@ module Archipelago
|
|
33
33
|
|
34
34
|
module Current
|
35
35
|
|
36
|
+
#
|
37
|
+
# Adds a few threaded methods to the normal ruby collections.
|
38
|
+
#
|
39
|
+
# NB: Will work slightly different than the unthreaded ones in certain circumstances.
|
40
|
+
#
|
41
|
+
module ThreadedCollection
|
42
|
+
|
43
|
+
#
|
44
|
+
# Like each, except calls +block+ within a new thread.
|
45
|
+
#
|
46
|
+
def t_each(&block)
|
47
|
+
threads = []
|
48
|
+
self.each do |args|
|
49
|
+
threads << Thread.new do
|
50
|
+
yield(args)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
threads.each do |thread|
|
54
|
+
thread.join
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Like collect, except calls +block+ within a new thread.
|
60
|
+
#
|
61
|
+
def t_collect(&block)
|
62
|
+
result = []
|
63
|
+
result.extend(Synchronized)
|
64
|
+
self.t_each do |args|
|
65
|
+
result.synchronize do
|
66
|
+
result << yield(args)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
return result
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Like select, except calls +block+ within a new thread.
|
74
|
+
#
|
75
|
+
def t_select(&block)
|
76
|
+
result = []
|
77
|
+
result.extend(Synchronized)
|
78
|
+
self.t_each do |args|
|
79
|
+
matches = yield(args)
|
80
|
+
result.synchronize do
|
81
|
+
result << args
|
82
|
+
end if matches
|
83
|
+
end
|
84
|
+
return result
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# Like reject, except calls +block+ within a new thread.
|
89
|
+
#
|
90
|
+
def t_reject(&block)
|
91
|
+
result = []
|
92
|
+
result.extend(Synchronized)
|
93
|
+
self.t_each do |args|
|
94
|
+
matches = yield(args)
|
95
|
+
result.synchronize do
|
96
|
+
result << args
|
97
|
+
end unless matches
|
98
|
+
end
|
99
|
+
return result
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
|
36
105
|
#
|
37
106
|
# A module that will allow any class to synchronize over any other
|
38
107
|
# object.
|
data/lib/archipelago/disco.rb
CHANGED
@@ -66,6 +66,11 @@ module Archipelago
|
|
66
66
|
#
|
67
67
|
THRIFTY_PUBLISHING = false
|
68
68
|
|
69
|
+
#
|
70
|
+
# The host we are running on.
|
71
|
+
#
|
72
|
+
HOST = "#{Socket::gethostbyname(Socket::gethostname)[0]}" rescue "localhost"
|
73
|
+
|
69
74
|
#
|
70
75
|
# A module to simplify publishing services.
|
71
76
|
#
|
@@ -138,7 +143,25 @@ module Archipelago
|
|
138
143
|
# We are always valid if we are able to reply.
|
139
144
|
#
|
140
145
|
def valid?
|
141
|
-
|
146
|
+
if defined?(@valid)
|
147
|
+
@valid
|
148
|
+
else
|
149
|
+
@valid = true
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
#
|
154
|
+
# Stops the publishing of this Publishable.
|
155
|
+
#
|
156
|
+
def stop!
|
157
|
+
if valid?
|
158
|
+
@valid = false
|
159
|
+
if defined?(Archipelago::Disco::MC) && @jockey == Archipelago::Disco::MC
|
160
|
+
@jockey.unpublish(self.service_id)
|
161
|
+
else
|
162
|
+
@jockey.stop!
|
163
|
+
end
|
164
|
+
end
|
142
165
|
end
|
143
166
|
|
144
167
|
#
|
@@ -153,12 +176,7 @@ module Archipelago
|
|
153
176
|
# Stuff that didnt fit in any of the other databases.
|
154
177
|
#
|
155
178
|
@metadata ||= @persistence_provider.get_hashish("metadata")
|
156
|
-
|
157
|
-
unless service_id
|
158
|
-
host = "#{Socket::gethostbyname(Socket::gethostname)[0]}" rescue "localhost"
|
159
|
-
service_id = @metadata["service_id"] ||= Digest::SHA1.hexdigest("#{host}:#{Time.new.to_f}:#{self.object_id}:#{rand(1 << 32)}")
|
160
|
-
end
|
161
|
-
return service_id
|
179
|
+
return @metadata["service_id"] ||= Digest::SHA1.hexdigest("#{HOST}:#{Time.new.to_f}:#{self.object_id}:#{rand(1 << 32)}").to_s
|
162
180
|
end
|
163
181
|
|
164
182
|
end
|
@@ -219,6 +237,16 @@ module Archipelago
|
|
219
237
|
class Query < ServiceDescription
|
220
238
|
end
|
221
239
|
|
240
|
+
#
|
241
|
+
# A class used to defined removed services.
|
242
|
+
#
|
243
|
+
class UnPublish
|
244
|
+
attr_reader :service_id
|
245
|
+
def initialize(service_id)
|
246
|
+
@service_id = service_id
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
222
250
|
#
|
223
251
|
# A class used to define an existing service.
|
224
252
|
#
|
@@ -249,6 +277,7 @@ module Archipelago
|
|
249
277
|
class ServiceLocker
|
250
278
|
attr_reader :hash
|
251
279
|
include Archipelago::Current::Synchronized
|
280
|
+
include Archipelago::Current::ThreadedCollection
|
252
281
|
def initialize(hash = nil)
|
253
282
|
super
|
254
283
|
@hash = hash || {}
|
@@ -274,7 +303,7 @@ module Archipelago
|
|
274
303
|
end
|
275
304
|
end
|
276
305
|
else
|
277
|
-
super(*args)
|
306
|
+
super(meth, *args, &block)
|
278
307
|
end
|
279
308
|
end
|
280
309
|
#
|
@@ -325,21 +354,35 @@ module Archipelago
|
|
325
354
|
# or if not given THRIFTY_REPLYING. Otherwise will reply with multicasts.
|
326
355
|
#
|
327
356
|
def initialize(options = {})
|
328
|
-
@
|
329
|
-
@thrifty_replying = options.include?(:thrifty_replying) ? options[:thrifty_replying] : THRIFTY_REPLYING
|
330
|
-
@thrifty_publishing = options.include?(:thrifty_publishing) ? options[:thrifty_publishing] : THRIFTY_PUBLISHING
|
331
|
-
@lookup_timeout = options[:lookup_timeout] || LOOKUP_TIMEOUT
|
332
|
-
@initial_lookup_standoff = options[:initial_lookup_standoff] || INITIAL_LOOKUP_STANDOFF
|
333
|
-
|
357
|
+
@valid = true
|
334
358
|
@remote_services = ServiceLocker.new
|
335
359
|
@local_services = ServiceLocker.new
|
336
360
|
@subscribed_services = Set.new
|
337
361
|
|
338
362
|
@incoming = Queue.new
|
339
363
|
@outgoing = Queue.new
|
340
|
-
|
364
|
+
|
341
365
|
@new_service_semaphore = MonitorMixin::ConditionVariable.new(Archipelago::Current::Lock.new)
|
342
|
-
|
366
|
+
|
367
|
+
setup(options)
|
368
|
+
|
369
|
+
start_listener
|
370
|
+
start_unilistener
|
371
|
+
start_shouter
|
372
|
+
start_picker
|
373
|
+
start_validator(options[:validation_interval] || VALIDATION_INTERVAL)
|
374
|
+
end
|
375
|
+
|
376
|
+
#
|
377
|
+
# Sets up this instance according to the given +options+.
|
378
|
+
#
|
379
|
+
def setup(options = {})
|
380
|
+
@thrifty_caching = options.include?(:thrifty_caching) ? options[:thrifty_caching] : THRIFTY_CACHING
|
381
|
+
@thrifty_replying = options.include?(:thrifty_replying) ? options[:thrifty_replying] : THRIFTY_REPLYING
|
382
|
+
@thrifty_publishing = options.include?(:thrifty_publishing) ? options[:thrifty_publishing] : THRIFTY_PUBLISHING
|
383
|
+
@lookup_timeout = options[:lookup_timeout] || LOOKUP_TIMEOUT
|
384
|
+
@initial_lookup_standoff = options[:initial_lookup_standoff] || INITIAL_LOOKUP_STANDOFF
|
385
|
+
|
343
386
|
@listener = UDPSocket.new
|
344
387
|
@unilistener = UDPSocket.new
|
345
388
|
|
@@ -371,29 +414,40 @@ module Archipelago
|
|
371
414
|
raise e
|
372
415
|
end
|
373
416
|
end
|
374
|
-
@unicast_address = "#{
|
417
|
+
@unicast_address = "#{HOST}:#{this_port}"
|
375
418
|
|
376
419
|
@sender = UDPSocket.new
|
377
420
|
@sender.connect(options[:address] || ADDRESS, options[:port] || PORT)
|
378
421
|
|
379
422
|
@unisender = UDPSocket.new
|
423
|
+
end
|
380
424
|
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
425
|
+
#
|
426
|
+
# Clears our local and remote services.
|
427
|
+
#
|
428
|
+
def clear!
|
429
|
+
@local_services = ServiceLocker.new
|
430
|
+
@remote_services = ServiceLocker.new
|
386
431
|
end
|
387
432
|
|
388
433
|
#
|
389
434
|
# Stops all the threads in this instance.
|
390
435
|
#
|
391
436
|
def stop!
|
392
|
-
@
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
437
|
+
if @valid
|
438
|
+
@valid = false
|
439
|
+
@local_services.each do |service_id, service_description|
|
440
|
+
self.unpublish(service_id)
|
441
|
+
end
|
442
|
+
@listener_thread.kill
|
443
|
+
@unilistener_thread.kill
|
444
|
+
@validator_thread.kill
|
445
|
+
@picker_thread.kill
|
446
|
+
until @outgoing.empty?
|
447
|
+
sleep(0.01)
|
448
|
+
end
|
449
|
+
@shouter_thread.kill
|
450
|
+
end
|
397
451
|
end
|
398
452
|
|
399
453
|
#
|
@@ -443,6 +497,17 @@ module Archipelago
|
|
443
497
|
end
|
444
498
|
end
|
445
499
|
|
500
|
+
#
|
501
|
+
# Removes the service with given +service_id+ from the published services.
|
502
|
+
#
|
503
|
+
def unpublish(service_id)
|
504
|
+
@local_services.delete(service_id)
|
505
|
+
@new_service_semaphore.broadcast
|
506
|
+
unless @thrifty_publishing
|
507
|
+
@outgoing << [nil, UnPublish.new(service_id)]
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
446
511
|
private
|
447
512
|
|
448
513
|
#
|
@@ -523,8 +588,8 @@ module Archipelago
|
|
523
588
|
end
|
524
589
|
|
525
590
|
#
|
526
|
-
# Start the thread picking incoming Records and
|
527
|
-
# handling them properly
|
591
|
+
# Start the thread picking incoming Records, Queries and UnPublishes and
|
592
|
+
# handling them properly.
|
528
593
|
#
|
529
594
|
def start_picker
|
530
595
|
@picker_thread = Thread.new do
|
@@ -544,6 +609,8 @@ module Archipelago
|
|
544
609
|
@remote_services[data[:service_id]] = data
|
545
610
|
@new_service_semaphore.broadcast
|
546
611
|
end
|
612
|
+
elsif Archipelago::Disco::UnPublish === data
|
613
|
+
@remote_services.delete(data.service_id)
|
547
614
|
end
|
548
615
|
rescue Exception => e
|
549
616
|
puts e
|
@@ -566,6 +633,12 @@ module Archipelago
|
|
566
633
|
|
567
634
|
end
|
568
635
|
|
636
|
+
#
|
637
|
+
# The default Archipelago::Disco::Jockey that is always available for lookups is Archipelago::Disco::MC.
|
638
|
+
#
|
639
|
+
# If you really need to you can customize it by defining MC_OPTIONS before loading disco.rb, and if you REALLY
|
640
|
+
# need to you can disable it completely by setting MC_DISABLED to true.
|
641
|
+
#
|
569
642
|
MC = Jockey.new(defined?(MC_OPTIONS) ? MC_OPTIONS : {}) unless defined?(MC_DISABLED) && MC_DISABLED
|
570
643
|
|
571
644
|
end
|
data/lib/archipelago/hashish.rb
CHANGED
@@ -48,6 +48,13 @@ module Archipelago
|
|
48
48
|
@lock = Archipelago::Current::Lock.new
|
49
49
|
end
|
50
50
|
#
|
51
|
+
# Close the @content_db and @timestamps_db behind this BerkeleyHashish
|
52
|
+
#
|
53
|
+
def close!
|
54
|
+
@content_db.close
|
55
|
+
@timestamps_db.close
|
56
|
+
end
|
57
|
+
#
|
51
58
|
# Returns a deep ( Marshal.load(Marshal.dump(o)) ) clone
|
52
59
|
# of the object represented by +key+.
|
53
60
|
#
|
@@ -70,12 +77,16 @@ module Archipelago
|
|
70
77
|
#
|
71
78
|
# Insert +value+ under +key+.
|
72
79
|
#
|
80
|
+
# Will call <b>value.save_hook(old_value)</b> and send
|
81
|
+
# it a block that does the actual saving if
|
82
|
+
# <b>value.respond_to?(:save_hook)</b>.
|
83
|
+
#
|
73
84
|
def []=(key, value)
|
74
85
|
@lock.synchronize_on(key) do
|
75
86
|
|
76
87
|
@content[key] = value
|
77
88
|
|
78
|
-
write_to_db(key, Marshal.dump(key), Marshal.dump(value))
|
89
|
+
write_to_db(key, Marshal.dump(key), Marshal.dump(value), value)
|
79
90
|
|
80
91
|
return value
|
81
92
|
|
@@ -85,13 +96,19 @@ module Archipelago
|
|
85
96
|
# Stores whatever is under +key+ if it is not the same as
|
86
97
|
# whats in the persistent db.
|
87
98
|
#
|
99
|
+
# Will call <b>value.save_hook(old_value)</b> and send
|
100
|
+
# it a block that does the actual saving if
|
101
|
+
# <b>value.respond_to?(:save_hook)</b> and
|
102
|
+
# a save is actually performed.
|
103
|
+
#
|
88
104
|
def store_if_changed(key)
|
89
105
|
@lock.synchronize_on(key) do
|
90
106
|
|
91
107
|
serialized_key = Marshal.dump(key)
|
92
|
-
|
108
|
+
value = @content[key]
|
109
|
+
serialized_value = Marshal.dump(value)
|
93
110
|
|
94
|
-
write_to_db(key, serialized_key, serialized_value) if @content_db[serialized_key] != serialized_value
|
111
|
+
write_to_db(key, serialized_key, serialized_value, value) if @content_db[serialized_key] != serialized_value
|
95
112
|
|
96
113
|
end
|
97
114
|
end
|
@@ -115,6 +132,19 @@ module Archipelago
|
|
115
132
|
end
|
116
133
|
end
|
117
134
|
#
|
135
|
+
# Will do +callable+.call(key, value) for each
|
136
|
+
# key-and-value pair in this Hashish.
|
137
|
+
#
|
138
|
+
# NB: This is totaly thread-unsafe, only do this
|
139
|
+
# for management or rescue!
|
140
|
+
#
|
141
|
+
def each(callable)
|
142
|
+
@content_db.each do |serialized_key, serialized_value|
|
143
|
+
key = Marshal.load(serialized_key)
|
144
|
+
callable.call(key, self.[](key))
|
145
|
+
end
|
146
|
+
end
|
147
|
+
#
|
118
148
|
# Delete +key+ and its value and timestamp.
|
119
149
|
#
|
120
150
|
def delete(key)
|
@@ -136,7 +166,27 @@ module Archipelago
|
|
136
166
|
# Write +key+, serialized as +serialized_key+ and
|
137
167
|
# +serialized_value+ to the db.
|
138
168
|
#
|
139
|
-
|
169
|
+
# Will call <b>value.save_hook(old_value)</b> and send
|
170
|
+
# it a block that does the actual saving if
|
171
|
+
# <b>value.respond_to?(:save_hook)</b>.
|
172
|
+
#
|
173
|
+
def write_to_db(key, serialized_key, serialized_value, value)
|
174
|
+
if value.respond_to?(:save_hook)
|
175
|
+
old_serialized_value = @content_db[serialized_key]
|
176
|
+
old_value = old_serialized_value ? Marshal.load(old_serialized_value) : nil
|
177
|
+
value.save_hook(old_value) do
|
178
|
+
do_write_to_db(key, serialized_key, serialized_value)
|
179
|
+
end
|
180
|
+
else
|
181
|
+
do_write_to_db(key, serialized_key, serialized_value)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
#
|
186
|
+
# Actually writes +key+ serialized as +serialized_key+ an
|
187
|
+
# +serialized_value+ to the db. Used by <b>write_to_db</b>.
|
188
|
+
#
|
189
|
+
def do_write_to_db(key, serialized_key, serialized_value)
|
140
190
|
now = Time.now
|
141
191
|
|
142
192
|
@content_db[serialized_key] = serialized_value
|
@@ -170,6 +220,8 @@ module Archipelago
|
|
170
220
|
def initialize(env_path)
|
171
221
|
env_path.mkpath
|
172
222
|
@env = BDB::Env.open(env_path, BDB::CREATE | BDB::INIT_MPOOL)
|
223
|
+
@berkeley_hashishes = []
|
224
|
+
@bdb_dbs = []
|
173
225
|
end
|
174
226
|
#
|
175
227
|
# Returns a cleverly cached (but slightly inefficient)
|
@@ -177,20 +229,31 @@ module Archipelago
|
|
177
229
|
# using +name+.
|
178
230
|
#
|
179
231
|
def get_cached_hashish(name)
|
180
|
-
BerkeleyHashish.new(name, @env)
|
232
|
+
hashish = BerkeleyHashish.new(name, @env)
|
233
|
+
@berkeley_hashishes << hashish
|
234
|
+
return hashish
|
181
235
|
end
|
182
236
|
#
|
183
237
|
# Returns a normal hash-like instance using +name+.
|
184
238
|
#
|
185
239
|
def get_hashish(name)
|
186
|
-
@env.open_db(BDB::HASH, name, nil, BDB::CREATE | BDB::NOMMAP)
|
240
|
+
db = @env.open_db(BDB::HASH, name, nil, BDB::CREATE | BDB::NOMMAP)
|
241
|
+
@bdb_dbs << db
|
242
|
+
return db
|
187
243
|
end
|
188
244
|
#
|
189
|
-
#
|
245
|
+
# Closes databases opened by this instance and removes the persistent files.
|
190
246
|
#
|
191
247
|
def unlink
|
192
|
-
|
193
|
-
|
248
|
+
@berkeley_hashishes.each do |h|
|
249
|
+
h.close!
|
250
|
+
end
|
251
|
+
@bdb_dbs.each do |d|
|
252
|
+
d.close
|
253
|
+
end
|
254
|
+
home = Pathname.new(@env.home)
|
255
|
+
@env.close
|
256
|
+
home.rmtree if home.exist?
|
194
257
|
end
|
195
258
|
end
|
196
259
|
|
data/lib/archipelago/pirate.rb
CHANGED
@@ -78,22 +78,37 @@ module Archipelago
|
|
78
78
|
# of required classes and modules at the chest.
|
79
79
|
#
|
80
80
|
def initialize(options = {})
|
81
|
-
|
81
|
+
setup(options)
|
82
|
+
|
83
|
+
@transaction = nil
|
84
|
+
|
85
|
+
start_service_updater(options[:initial_service_update_interval] || INITIAL_SERVICE_UPDATE_INTERVAL,
|
86
|
+
options[:maximum_service_update_interval] || MAXIMUM_SERVICE_UPDATE_INTERVAL)
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Sets up this instance with the given +options+.
|
92
|
+
#
|
93
|
+
def setup(options = {})
|
94
|
+
@treasure_map ||= nil
|
95
|
+
if defined?(Archipelago::Disco::MC)
|
96
|
+
@treasure_map.stop! if @treasure_map && @treasure_map != Archipelago::Disco::MC
|
97
|
+
@treasure_map = options.include?(:jockey_options) ? Archipelago::Disco::Jockey.new(options[:jockey_options]) : Archipelago::Disco::MC
|
98
|
+
else
|
99
|
+
@treasure_map.stop! if @treasure_map
|
100
|
+
@treasure_map = Archipelago::Disco::Jockey.new(options[:jockey_options] || {})
|
101
|
+
end
|
82
102
|
|
83
103
|
@chest_description = CHEST_DESCRIPTION.merge(options[:chest_description] || {})
|
84
104
|
@tranny_description = TRANNY_DESCRIPTION.merge(options[:tranny_description] || {})
|
85
|
-
@jockey_options = options[:jockey_options] || {}
|
86
105
|
|
87
|
-
@chest_eval_files
|
106
|
+
@chest_eval_files ||= []
|
107
|
+
@chest_eval_files += options[:chest_eval_files] || []
|
88
108
|
|
89
|
-
@chests_having_evaluated
|
90
|
-
|
91
|
-
start_service_updater(options[:initial_service_update_interval] || INITIAL_SERVICE_UPDATE_INTERVAL,
|
92
|
-
options[:maximum_service_update_interval] || MAXIMUM_SERVICE_UPDATE_INTERVAL)
|
109
|
+
@chests_having_evaluated ||= {}
|
93
110
|
|
94
111
|
@yar_counter = 0
|
95
|
-
|
96
|
-
@transaction = nil
|
97
112
|
end
|
98
113
|
|
99
114
|
#
|
@@ -199,10 +214,36 @@ module Archipelago
|
|
199
214
|
end
|
200
215
|
|
201
216
|
#
|
202
|
-
# Stops the service update thread for this Pirate
|
217
|
+
# Stops the service update thread for this Pirate and also unpublishes and/or
|
218
|
+
# stops the Jockey.
|
203
219
|
#
|
204
220
|
def stop!
|
205
221
|
@service_update_thread.kill
|
222
|
+
unless defined?(Archipelago::Disco::MC) && @treasure_map && @treasure_map == Archipelago::Disco::MC
|
223
|
+
@treasure_map.stop!
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
#
|
228
|
+
# Will do +callable+.call(key, value)
|
229
|
+
# for each key-and-value pair in this database network.
|
230
|
+
#
|
231
|
+
# NB: This is totaly thread-unsafe, only do this
|
232
|
+
# for management or rescue!
|
233
|
+
#
|
234
|
+
def each(callable)
|
235
|
+
@chests.t_each do |service_id, chest|
|
236
|
+
chest[:service].each(callable)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
#
|
241
|
+
# Does an immediate update of our service lists.
|
242
|
+
#
|
243
|
+
def update_services!
|
244
|
+
@chests = @treasure_map.lookup(Archipelago::Disco::Query.new(@chest_description), 0)
|
245
|
+
evaluate_in_chests
|
246
|
+
@trannies = @treasure_map.lookup(Archipelago::Disco::Query.new(@tranny_description), 0)
|
206
247
|
end
|
207
248
|
|
208
249
|
private
|
@@ -271,9 +312,7 @@ module Archipelago
|
|
271
312
|
# +initial+ and +maximum+ seconds.
|
272
313
|
#
|
273
314
|
def start_service_updater(initial, maximum)
|
274
|
-
|
275
|
-
evaluate_in_chests
|
276
|
-
@trannies = @treasure_map.lookup(Archipelago::Disco::Query.new(@tranny_description), 0)
|
315
|
+
update_services!
|
277
316
|
@service_update_thread = Thread.start do
|
278
317
|
standoff = initial
|
279
318
|
loop do
|
@@ -281,9 +320,7 @@ module Archipelago
|
|
281
320
|
sleep(standoff)
|
282
321
|
standoff *= 2
|
283
322
|
standoff = maximum if standoff > maximum
|
284
|
-
|
285
|
-
evaluate_in_chests
|
286
|
-
@trannies = @treasure_map.lookup(Archipelago::Disco::Query.new(@tranny_description), 0)
|
323
|
+
update_services!
|
287
324
|
rescue Exception => e
|
288
325
|
puts e
|
289
326
|
pp e.backtrace
|
@@ -291,6 +328,7 @@ module Archipelago
|
|
291
328
|
end
|
292
329
|
end
|
293
330
|
end
|
331
|
+
|
294
332
|
end
|
295
333
|
|
296
334
|
end
|