Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

better support around multithreading

  • Loading branch information...
commit ed20565a08edf678660c66cfaea3f24e32fddbd4 1 parent a071c42
@btatnall btatnall authored
View
2  Gemfile
@@ -3,6 +3,6 @@ source :gemcutter
gem "activerecord", "~> 2.3.5"
group :test do
- gem "rspec", ">= 2.0.0.beta.8"
+ gem "rspec", "2.0.0.beta.8"
gem "jeweler"
end
View
14 lib/merged_default_scopes.rb
@@ -4,16 +4,20 @@
module MergedDefaultScopes
module ClassMethods
def default_scope(options = {})
- if scoped_methods
- with_scope(:find => options, :create => options[:conditions].is_a?(Hash) ? options[:conditions] : {}) do
- scoped_methods << scoped_methods.last
- end
+ new_scope = { :find => options, :create => options[:conditions].is_a?(Hash) ? options[:conditions] : {} }
+ if scoped_methods.empty?
+ self.default_scoping << new_scope
+ self.scoped_methods << new_scope
else
- super(options)
+ with_scope(new_scope) do
+ self.default_scoping << current_scoped_methods
+ self.scoped_methods << current_scoped_methods
+ end
end
end
def clear_default_scope
+ default_scoping.clear
scoped_methods.clear
end
end
View
1  spec/db/schema.rb
@@ -4,4 +4,3 @@
t.column :name, :string
end
end
-
View
72 spec/merged_default_scopes_spec.rb
@@ -6,6 +6,49 @@ class SomeModel < ActiveRecord::Base
describe MergedDefaultScopes do
before(:each) { SomeModel.__send__ :clear_default_scope }
+ describe "#clear_default_scope" do
+ it "clears scope" do
+ SomeModel.class_eval do
+ default_scope :order => :name
+ default_scope :conditions => {:deleted_at => nil}
+ clear_default_scope
+ end
+ SomeModel.__send__(:scope, :find).
+ should be_nil
+ end
+
+ it "clears for new threads" do
+ monitor = Monitor.new
+ condition = monitor.new_cond
+ counter = 0
+ t1 = Thread.new do
+ SomeModel.class_eval do
+ default_scope :order => :name
+ end
+ counter += 1
+ end
+
+ t2 = Thread.new do
+ monitor.synchronize do
+ condition.wait_until { counter == 1 }
+ SomeModel.class_eval do
+ clear_default_scope
+ end
+ counter += 1
+ end
+ end
+
+ t3 = Thread.new do
+ monitor.synchronize do
+ condition.wait_until { counter == 2 }
+ SomeModel.__send__(:scope, :find).
+ should be_nil
+ end
+ end
+ [t1,t2,t3].each { |t| t.join }
+ end
+ end
+
describe "#default_scope" do
it "merges multiple calls" do
SomeModel.class_eval do
@@ -15,17 +58,28 @@ class SomeModel < ActiveRecord::Base
SomeModel.__send__(:scope, :find).
should == {:order => :name, :conditions => {:deleted_at => nil}}
end
- end
- describe "#clear_default_scope" do
- it "clears default scopes" do
- SomeModel.class_eval do
- default_scope :order => :name
- default_scope :conditions => {:deleted_at => nil}
- clear_default_scope
+ it "persists merges across threads" do
+ monitor = Monitor.new
+ condition = monitor.new_cond
+ counter = 0
+ t1 = Thread.new do
+ SomeModel.class_eval do
+ default_scope :order => :name
+ end
+ SomeModel.__send__(:scope, :find).
+ should == {:order => :name}
+ counter += 1
end
- SomeModel.__send__(:scope, :find).should be_nil
+
+ t2 = Thread.new do
+ monitor.synchronize do
+ condition.wait_until { counter == 1 }
+ SomeModel.__send__(:scope, :find).
+ should == {:order => :name}
+ end
+ end
+ [t1,t2].each { |t| t.join }
end
end
-
end
View
21 spec/spec_helper.rb
@@ -1,16 +1,19 @@
$LOAD_PATH.unshift(File.dirname(__FILE__))
+require 'rubygems'
require 'merged_default_scopes'
require 'rspec'
-require "sqlite3"
+adapter = nil
+config = { :database => ":memory:" }
+if RUBY_PLATFORM =~ /java/
+ require "jdbc/sqlite3"
+ require "active_record/connection_adapters/jdbcsqlite3_adapter"
+ config[:adapter] = "jdbcsqlite3"
+else
+ require "sqlite3"
+ config[:adapter] = "sqlite3"
+end
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
-ActiveRecord::Base.establish_connection(
- :adapter => "sqlite3",
- :database => ":memory:"
-)
+ActiveRecord::Base.establish_connection(config)
ActiveRecord::Migration.verbose = false
load(File.dirname(__FILE__) + "/db/schema.rb")
-
-class AuditableModel < ActiveRecord::Base; end
-
-
Please sign in to comment.
Something went wrong with that request. Please try again.