Class: Concurrent::Transaction

Inherits:
Object
  • Object
show all
Defined in:
lib/concurrent/tvar.rb

Defined Under Namespace

Classes: ReadLogEntry

Constant Summary collapse

ABORTED =
::Object.new
AbortError =
Class.new(StandardError)
LeaveError =
Class.new(StandardError)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeTransaction

Returns a new instance of Transaction



172
173
174
175
# File 'lib/concurrent/tvar.rb', line 172

def initialize
  @read_log  = []
  @write_log = {}
end

Class Method Details

.currentundocumented



248
249
250
# File 'lib/concurrent/tvar.rb', line 248

def self.current
  Thread.current[:current_tvar_transaction]
end

.current=(transaction) ⇒ undocumented



252
253
254
# File 'lib/concurrent/tvar.rb', line 252

def self.current=(transaction)
  Thread.current[:current_tvar_transaction] = transaction
end

Instance Method Details

#abortundocumented



213
214
215
# File 'lib/concurrent/tvar.rb', line 213

def abort
  unlock
end

#commitundocumented



217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/concurrent/tvar.rb', line 217

def commit
  return false unless valid?

  @write_log.each_pair do |tvar, value|
    tvar.unsafe_value = value
    tvar.unsafe_increment_version
  end

  unlock

  true
end

#read(tvar) ⇒ undocumented



177
178
179
180
181
182
183
184
185
186
# File 'lib/concurrent/tvar.rb', line 177

def read(tvar)
  Concurrent::abort_transaction unless valid?

  if @write_log.has_key? tvar
    @write_log[tvar]
  else
    @read_log.push(ReadLogEntry.new(tvar, tvar.unsafe_version))
    tvar.unsafe_value
  end
end

#unlockundocumented



242
243
244
245
246
# File 'lib/concurrent/tvar.rb', line 242

def unlock
  @write_log.each_key do |tvar|
    tvar.unsafe_lock.unlock
  end
end

#valid?Boolean

Returns:

  • (Boolean)


230
231
232
233
234
235
236
237
238
239
240
# File 'lib/concurrent/tvar.rb', line 230

def valid?
  @read_log.each do |log_entry|
    unless @write_log.has_key? log_entry.tvar
      if log_entry.tvar.unsafe_version > log_entry.version
        return false
      end
    end
  end

  true
end

#write(tvar, value) ⇒ undocumented



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/concurrent/tvar.rb', line 188

def write(tvar, value)
  # Have we already written to this TVar?

  unless @write_log.has_key? tvar
    # Try to lock the TVar

    unless tvar.unsafe_lock.try_lock
      # Someone else is writing to this TVar - abort
      Concurrent::abort_transaction
    end

    # If we previously wrote to it, check the version hasn't changed

    @read_log.each do |log_entry|
      if log_entry.tvar == tvar and tvar.unsafe_version > log_entry.version
        Concurrent::abort_transaction
      end
    end
  end

  # Record the value written

  @write_log[tvar] = value
end