fixes for conversations and sharding for rails 3

Change-Id: I86bde6da2cc006e92c00113dccb95f100c2dadee
Reviewed-on: https://gerrit.instructure.com/29393
Reviewed-by: Cody Cutrer <cody@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
Product-Review: James Williams  <jamesw@instructure.com>
QA-Review: James Williams  <jamesw@instructure.com>
This commit is contained in:
James Williams 2014-01-28 11:57:43 -07:00
parent 36a815448b
commit 88dcdc266c
5 changed files with 36 additions and 22 deletions

View File

@ -40,6 +40,7 @@ class Conversation < ActiveRecord::Base
def reload(options = nil)
@current_context_strings = {}
@participants = nil
super
end
@ -415,7 +416,8 @@ class Conversation < ActiveRecord::Base
cp.update_attribute(:tags, updated_tags)
if cp.user.shard != self.shard
cp.user.shard.activate do
ConversationParticipant.where(:conversation_id => self, :user_id => cp.user_id).update_all(:tags => serialized_tags(cp.tags))
ConversationParticipant.where(:conversation_id => self, :user_id => cp.user_id).
update_all(:tags => serialized_tags(cp.tags))
end
end
end
@ -581,10 +583,12 @@ class Conversation < ActiveRecord::Base
def regenerate_private_hash!(user_ids = nil)
return unless private?
self.private_hash = Conversation.private_hash_for(user_ids ||
Shard.birth.activate { self.conversation_participants.map(&:user_id) } )
Shard.birth.activate { self.conversation_participants.reload.map(&:user_id) } )
return unless private_hash_changed?
existing = self.shard.activate do
ConversationParticipant.find_by_private_hash(private_hash).try(:conversation)
ConversationParticipant.send(:with_exclusive_scope) do
ConversationParticipant.find_by_private_hash(private_hash).try(:conversation)
end
end
if existing
merge_into(existing)
@ -636,7 +640,7 @@ class Conversation < ActiveRecord::Base
if cp.user.shard != self.shard
cp.user.shard.activate do
ConversationParticipant.where(:conversation_id => self, :user_id => cp.user_id).
update_all(:conversation_id => other)
update_all(:conversation_id => other)
end
end
# create a new duplicate cp on the target conversation's shard
@ -651,7 +655,6 @@ class Conversation < ActiveRecord::Base
end
end
end
if other.shard == self.shard
conversation_messages.update_all(:conversation_id => other)
else

View File

@ -459,8 +459,8 @@ class ConversationParticipant < ActiveRecord::Base
end
def move_to_user(new_user)
self.class.send :with_exclusive_scope do
conversation.shard.activate do
conversation.shard.activate do
self.class.send :with_exclusive_scope do
old_shard = self.user.shard
conversation.conversation_messages.where(:author_id => user_id).update_all(:author_id => new_user)
if existing = conversation.conversation_participants.find_by_user_id(new_user)
@ -480,6 +480,8 @@ class ConversationParticipant < ActiveRecord::Base
new_cp.save!
end
end
end
self.class.send :with_exclusive_scope do
conversation.regenerate_private_hash! if private?
end
end

View File

@ -1057,12 +1057,21 @@ unless CANVAS_RAILS2
alias_method_chain :delete_all, :limit
end
def with_each_shard
if block_given?
Array(yield(self))
else
self.to_a
def with_each_shard(*args)
scope = self
if (owner = self.try(:proxy_association).try(:owner)) && self.shard_category != :explicit
scope = scope.shard(owner)
end
scope = scope.shard(args) if args.any?
if block_given?
scope.activate{|rel| yield(rel) }
else
scope.to_a
end
end
ActiveRecord::Associations::CollectionProxy.class_eval do
delegate :with_each_shard, :to => :scoped
end
end

View File

@ -206,7 +206,7 @@ describe ConversationParticipant do
Account.site_admin.stubs(:grants_right?).with(@admin_user, :become_user).returns(false)
convos = @target_user.conversations.for_masquerading_user(@admin_user)
convos.size.should eql 4
convos.should eql @target_user.conversations.to_a
convos.should == @target_user.conversations.to_a
end
it "should limit others to their associated root accounts" do
@ -414,7 +414,7 @@ describe ConversationParticipant do
ConversationParticipant.send :with_scope, :find => {:conditions => ["user_id = ?", @user1.id]} do
c.move_to_user @user2
end
lambda{ c.reload }.should raise_error # deleted
lambda{ Conversation.find(c.conversation_id) }.should raise_error # deleted

View File

@ -1124,44 +1124,44 @@ describe Conversation do
context "matching shards" do
it "user from another shard participating in both conversations" do
merge_and_check(@sender, @conversation1, @conversation2, @user2, @user2)
@conversation2.associated_shards.should == [Shard.default, @shard1]
@conversation2.associated_shards.sort_by(&:id).should == [Shard.default, @shard1].sort_by(&:id)
end
it "user from another shard participating in source conversation only" do
merge_and_check(@sender, @conversation1, @conversation2, @user2, nil)
@conversation2.associated_shards.should == [Shard.default, @shard1]
@conversation2.associated_shards.sort_by(&:id).should == [Shard.default, @shard1].sort_by(&:id)
end
end
context "differing shards" do
it "user from source shard participating in both conversations" do
merge_and_check(@sender, @conversation1, @conversation3, @user1, @user1)
@conversation3.associated_shards.should == [@shard1, Shard.default]
@conversation3.associated_shards.sort_by(&:id).should == [@shard1, Shard.default].sort_by(&:id)
end
it "user from destination shard participating in both conversations" do
merge_and_check(@sender, @conversation1, @conversation3, @user2, @user2)
@conversation3.associated_shards.should == [@shard1, Shard.default]
@conversation3.associated_shards.sort_by(&:id).should == [@shard1, Shard.default].sort_by(&:id)
end
it "user from third shard participating in both conversations" do
merge_and_check(@sender, @conversation1, @conversation3, @user3, @user3)
@conversation3.associated_shards.sort_by(&:id).should == [Shard.default, @shard1, @shard2]
@conversation3.associated_shards.sort_by(&:id).should == [Shard.default, @shard1, @shard2].sort_by(&:id)
end
it "user from source shard participating in source conversation only" do
merge_and_check(@sender, @conversation1, @conversation3, @user1, nil)
@conversation3.associated_shards.should == [@shard1, Shard.default]
@conversation3.associated_shards.sort_by(&:id).should == [@shard1, Shard.default].sort_by(&:id)
end
it "user from destination shard participating in source conversation only" do
merge_and_check(@sender, @conversation1, @conversation3, @user2, nil)
@conversation3.associated_shards.should == [@shard1, Shard.default]
@conversation3.associated_shards.sort_by(&:id).should == [@shard1, Shard.default].sort_by(&:id)
end
it "user from third shard participating in source conversation only" do
merge_and_check(@sender, @conversation1, @conversation3, @user3, nil)
@conversation3.associated_shards.sort_by(&:id).should == [Shard.default, @shard1, @shard2]
@conversation3.associated_shards.sort_by(&:id).should == [Shard.default, @shard1, @shard2].sort_by(&:id)
end
end
end