Class: Archipelago::Pirate::Captain

Inherits:
Object
  • Object
show all
Defined in:
lib/archipelago/pirate.rb

Overview

The class that actually keeps track of the Archipelago::Treasure:Chests and the Archipelago::Treasure:Dubloons in them.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Captain

Initialize an instance using an Archipelago::Disco::Jockey with :jockey_options if given, that looks for new services :initial_service_update_interval or INITIAL_SERVICE_UPDATE_INTERVAL, when it starts and never slower than every :maximum_service_update_interval or MAXIMUM_SERVICE_UPDATE_INTERVAL.

Will look for Archipelago::Treasure::Chests matching :chest_description or CHEST_DESCRIPTION and Archipelago::Tranny::Managers matching :tranny_description or TRANNY_DESCRIPTION.

Will send off all :chest_eval_files to any chest found for possible evaluation to ensure existence of required classes and modules at the chest.



80
81
82
83
84
85
86
87
88
# File 'lib/archipelago/pirate.rb', line 80

def initialize(options = {})
  setup(options)

  @transaction = nil

  start_service_updater(options[:initial_service_update_interval] || INITIAL_SERVICE_UPDATE_INTERVAL,
                        options[:maximum_service_update_interval] || MAXIMUM_SERVICE_UPDATE_INTERVAL)

end

Instance Attribute Details

#chestsObject (readonly)

Returns the value of attribute chests.



68
69
70
# File 'lib/archipelago/pirate.rb', line 68

def chests
  @chests
end

#tranniesObject (readonly)

Returns the value of attribute trannies.



68
69
70
# File 'lib/archipelago/pirate.rb', line 68

def trannies
  @trannies
end

#treasure_mapObject (readonly)

Returns the value of attribute treasure_map.



68
69
70
# File 'lib/archipelago/pirate.rb', line 68

def treasure_map
  @treasure_map
end

Instance Method Details

#[](key, transaction = nil) ⇒ Object

Get a value from the distributed database network using a key, optionally within a transaction.



118
119
120
# File 'lib/archipelago/pirate.rb', line 118

def [](key, transaction = nil)
  responsible_chest(key)[:service][key, transaction || @transaction]
end

#[]=(key, p1, p2 = nil) ⇒ Object

Write a value to the distributed database network, optionally inside a transaction.

Usage:

  • p[“my key”, transaction] = value

  • p[“my key”] = value



130
131
132
133
134
135
136
# File 'lib/archipelago/pirate.rb', line 130

def []=(key, p1, p2 = nil)
  if @transaction && p2.nil?
    p2 = p1
    p1 = @transaction 
  end
  responsible_chest(key)[:service][key, p1] = p2
end

#abort!Object

Abort the transaction we are a member of and forget about it.



203
204
205
206
# File 'lib/archipelago/pirate.rb', line 203

def abort!
  @transaction.abort!
  @transaction = nil
end

#beginObject

Return a clone of this instance bound to a newly created transaction.



149
150
151
152
153
154
155
156
157
158
# File 'lib/archipelago/pirate.rb', line 149

def begin
  raise NoTransactionManagerAvailableException.new(self) if @trannies.empty?

  rval = self.clone
  rval.instance_eval do
    @transaction = @trannies.values.first[:service].begin
  end

  return rval
end

#commit!Object

Commit the transaction we are a member of and forget about it.



195
196
197
198
# File 'lib/archipelago/pirate.rb', line 195

def commit!
  @transaction.commit!
  @transaction = nil
end

#delete(key, transaction = nil) ⇒ Object

Delete a value from the distributed database network, optionally inside a transaction.



142
143
144
# File 'lib/archipelago/pirate.rb', line 142

def delete(key, transaction = nil)
  responsible_chest(key)[:service].delete(key, transaction || @transaction)
end

#each(callable) ⇒ Object

Will do callable.call(key, value) for each key-and-value pair in this database network.

NB: This is totaly thread-unsafe, only do this for management or rescue!



234
235
236
237
238
# File 'lib/archipelago/pirate.rb', line 234

def each(callable)
  @chests.t_each do |service_id, chest|
    chest[:service].each(callable)
  end
end

#evaluate!(filename) ⇒ Object

Evaluate this file in all known chests.



187
188
189
190
# File 'lib/archipelago/pirate.rb', line 187

def evaluate!(filename)
  @chest_eval_files << filename
  evaluate_in_chests
end

#setup(options = {}) ⇒ Object

Sets up this instance with the given options.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/archipelago/pirate.rb', line 93

def setup(options = {})
  @treasure_map ||= nil
  if defined?(Archipelago::Disco::MC)
    @treasure_map.stop! if @treasure_map && @treasure_map != Archipelago::Disco::MC
    @treasure_map = options.include?(:jockey_options) ? Archipelago::Disco::Jockey.new(options[:jockey_options]) : Archipelago::Disco::MC
  else
    @treasure_map.stop! if @treasure_map
    @treasure_map = Archipelago::Disco::Jockey.new(options[:jockey_options] || {})
  end

  @chest_description = CHEST_DESCRIPTION.merge(options[:chest_description] || {})
  @tranny_description = TRANNY_DESCRIPTION.merge(options[:tranny_description] || {})

  @chest_eval_files ||= []
  @chest_eval_files += options[:chest_eval_files] || []

  @chests_having_evaluated ||= {}

  @yar_counter = 0
end

#stop!Object

Stops the service update thread for this Pirate and also unpublishes and/or stops the Jockey.



220
221
222
223
224
225
# File 'lib/archipelago/pirate.rb', line 220

def stop!
  @service_update_thread.kill
  unless defined?(Archipelago::Disco::MC) && @treasure_map && @treasure_map == Archipelago::Disco::MC
    @treasure_map.stop!
  end
end

#transaction(&block) ⇒ Object

Execute block within a transaction.

Will commit! transaction after the block is finished unless the transaction is aborted or commited already.

Will abort! the transaction if any exception is raised.



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/archipelago/pirate.rb', line 168

def transaction(&block) #:yields: transaction
  raise NoTransactionManagerAvailableException.new(self) if @trannies.empty?

  @transaction = @trannies.values.first[:service].begin
  begin
    yield(@transaction)
    @transaction.commit! if @transaction.state == :active
  rescue Exception => e
    @transaction.abort! unless @transaction.state == :aborted
    puts e
    pp e.backtrace
  ensure
    @transaction = nil
  end
end

#update_services!Object

Does an immediate update of our service lists.



243
244
245
246
247
# File 'lib/archipelago/pirate.rb', line 243

def update_services!
  @chests = @treasure_map.lookup(Archipelago::Disco::Query.new(@chest_description), 0)
  evaluate_in_chests
  @trannies = @treasure_map.lookup(Archipelago::Disco::Query.new(@tranny_description), 0)
end

#yar!Object

Yarrr!



211
212
213
214
# File 'lib/archipelago/pirate.rb', line 211

def yar!
  @yar_counter += 1
  'yar!'
end