archipelago 0.1.1 → 0.2.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/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
|