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 collapse

Attributes inherited from Client::Base

#jockey

Instance Method Summary collapse

Methods inherited from Client::Base

#stop!

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.



84
85
86
87
88
89
90
91
# File 'lib/archipelago/pirate.rb', line 84

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

  @transaction = nil

  start_service_updater

end

Instance Attribute Details

#chestsObject (readonly)

Returns the value of attribute chests.



76
77
78
# File 'lib/archipelago/pirate.rb', line 76

def chests
  @chests
end

#tranniesObject (readonly)

Returns the value of attribute trannies.



76
77
78
# File 'lib/archipelago/pirate.rb', line 76

def trannies
  @trannies
end

Instance Method Details

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

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



121
122
123
# File 'lib/archipelago/pirate.rb', line 121

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



133
134
135
136
137
138
139
# File 'lib/archipelago/pirate.rb', line 133

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.



215
216
217
218
# File 'lib/archipelago/pirate.rb', line 215

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

#active_transactionObject

Returns our active transaction, if any.



166
167
168
# File 'lib/archipelago/pirate.rb', line 166

def active_transaction
  @transaction
end

#beginObject

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



152
153
154
155
156
157
158
159
160
161
# File 'lib/archipelago/pirate.rb', line 152

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.



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

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

#delete(key, transaction = nil) ⇒ Object

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



145
146
147
# File 'lib/archipelago/pirate.rb', line 145

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!



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

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.



199
200
201
202
# File 'lib/archipelago/pirate.rb', line 199

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)


113
114
115
# File 'lib/archipelago/pirate.rb', line 113

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

#setup(options = {}) ⇒ Object

Sets up this instance with the given options.



96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/archipelago/pirate.rb', line 96

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

  @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

#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.



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/archipelago/pirate.rb', line 178

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

  @transaction = @trannies.values.first[:service].begin
  begin
    begin
      return yield(@transaction)
    ensure
      raise CommitFailedException.new(self, @transaction) unless @transaction.commit! == :commited
    end
  rescue Exception => e
    @transaction.abort! unless @transaction.state == :aborted
    raise e
  ensure
    @transaction = nil
  end
end

#update_services!Object

Does an immediate update of our service lists.



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

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

#yar!Object

Yarrr!



223
224
225
226
# File 'lib/archipelago/pirate.rb', line 223

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