Skip to content
This repository has been archived by the owner on Jun 22, 2021. It is now read-only.

Commit

Permalink
Initial import.
Browse files Browse the repository at this point in the history
  • Loading branch information
notahat committed Apr 21, 2010
0 parents commit 3022802
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 0 deletions.
20 changes: 20 additions & 0 deletions MIT-LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright (c) 2010 [name of plugin creator]

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 changes: 13 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
BetterLocking
=============

Introduction goes here.


Example
=======

Example goes here.


Copyright (c) 2010 [name of plugin creator], released under the MIT license
23 changes: 23 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'

desc 'Default: run unit tests.'
task :default => :test

desc 'Test the better_locking plugin.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end

desc 'Generate documentation for the better_locking plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'BetterLocking'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
end
1 change: 1 addition & 0 deletions init.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require 'better_locking'
1 change: 1 addition & 0 deletions install.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Install hook code here
Binary file added lib/.better_locking.rb.swp
Binary file not shown.
65 changes: 65 additions & 0 deletions lib/better_locking.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
module BetterLocking

def self.included(base)
base.extend(ClassMethods)
end

def confirm_lock!
raise LockNotHeld unless ActiveRecord::Base.locked_objects.include?(self)
end

module ClassMethods
def transaction_with_locks(*objects)
objects = objects.flatten.compact
return if objects.all? {|object| ActiveRecord::Base.locked_objects.include?(object) }

minimum_transaction_level = (Rails.env.test? ? 1 : 0)
raise LockMustBeOutermostTransaction unless connection.open_transactions == minimum_transaction_level

objects.sort_by {|object| [object.class.name, object.send(object.class.primary_key)] }
begin
ActiveRecord::Base.locked_objects = nil
transaction do
begin
objects.each(&:lock!)
ActiveRecord::Base.locked_objects = objects
rescue ActiveRecord::StatementInvalid => exception
if exception.message =~ /Deadlock/
raise RetryTransaction
else
raise
end
end

yield
end
rescue RetryTransaction
retry
ensure
ActiveRecord::Base.locked_objects = nil
end
end

def locked_objects=(objects)
@locked_objects = objects
end

def locked_objects
@locked_objects || []
end
end

class LockMustBeOutermostTransaction < RuntimeError
end

class LockNotHeld < RuntimeError
end

class RetryTransaction < RuntimeError
end

end

class ActiveRecord::Base
include BetterLocking
end
4 changes: 4 additions & 0 deletions tasks/better_locking_tasks.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# desc "Explaining what the task does"
# task :better_locking do
# # Task goes here
# end
8 changes: 8 additions & 0 deletions test/better_locking_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require 'test_helper'

class BetterLockingTest < ActiveSupport::TestCase
# Replace this with your real tests.
test "the truth" do
assert true
end
end
3 changes: 3 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require 'rubygems'
require 'active_support'
require 'active_support/test_case'
1 change: 1 addition & 0 deletions uninstall.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Uninstall hook code here

0 comments on commit 3022802

Please sign in to comment.