Class: Archipelago::Pirate::Captain

Inherits:
Client::Base 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

Attributes inherited from Client::Base

#debug_callable, #jockey, #service_descriptions, #services

Attributes included from Disco::Camel

#jockey

Instance Method Summary collapse

Methods inherited from Client::Base

#method_missing, #setup_client, #stop!, #update_services!

Constructor Details

#initialize(options = {}) ⇒ Captain

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.



82
83
84
85
# File 'lib/archipelago/pirate.rb', line 82

def initialize(options = {})
  @transaction = nil
  setup(options)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Archipelago::Client::Base

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.

Returns the new state of the transaction.



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

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

#active_transactionObject

Returns our active transaction, if any.



163
164
165
# File 'lib/archipelago/pirate.rb', line 163

def active_transaction
  @transaction
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 self.trannies.empty?

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

  return rval
end

#commit!Object

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

Returns the new state of the transaction.



205
206
207
208
209
210
211
# File 'lib/archipelago/pirate.rb', line 205

def commit!
  begin
    return @transaction.commit!
  ensure
    @transaction = nil
  end
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!



241
242
243
244
245
# File 'lib/archipelago/pirate.rb', line 241

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

#evaluate!(filename) ⇒ Object

Evaluate this file in all known chests.



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

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

#include?(key, transaction = nil) ⇒ Boolean

Returns true if this Captain includes the given key, optionally within a transaction.

Returns:

  • (Boolean)


110
111
112
# File 'lib/archipelago/pirate.rb', line 110

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

#responsible_chest(key) ⇒ Object

Get the chest responsible for key.



250
251
252
253
254
# File 'lib/archipelago/pirate.rb', line 250

def responsible_chest(key)
  raise NoRemoteDatabaseAvailableException.new(self) if self.chests.empty?

  return get_least_greater_than(:chests, key, 1).first
end

#setup(options = {}) ⇒ Object

Sets up this instance with the given options.



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/archipelago/pirate.rb', line 90

def setup(options = {})
  @chest_eval_files ||= []
  @chest_eval_files += options[:chest_eval_files] || []
  @chests_having_evaluated ||= {}

  @yar_counter = 0

  options.merge!({
                   :service_descriptions => {
                     :chests => CHEST_DESCRIPTION.merge(options[:chest_description] || {}),
                     :trannies => TRANNY_DESCRIPTION.merge(options[:tranny_description] || {})
                   }
                 })

  setup_client(options)
end

#successor(service_id) ⇒ Object

Gets the successor of service_id in the array of services.



259
260
261
262
# File 'lib/archipelago/pirate.rb', line 259

def successor(service_id)
  return nil if self.chests.empty?
  return get_least_greater_than(:chests, service_id, 1).first
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.



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/archipelago/pirate.rb', line 175

def transaction(&block) #:yields: a clone of this Archipelago::Pirate::Captain with the given transaction as default @transaction.
  raise NoTransactionManagerAvailableException.new(self) if self.trannies.empty?

  my_clone = self.begin
  transa = my_clone.active_transaction
  begin
    begin
      return yield(my_clone)
    ensure
      raise CommitFailedException.new(my_clone, transa) unless transa.commit! == :commited
    end
  rescue Exception => e
    transa.abort! unless transa.state == :aborted
    raise e
  end
end

#yar!Object

Yarrr!



229
230
231
232
# File 'lib/archipelago/pirate.rb', line 229

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