DG MS; optimized local comments to be batched; backfilled more tests

This commit is contained in:
danielgrippi 2011-09-15 11:22:25 -07:00
parent cfa260927d
commit ec011f0800
7 changed files with 91 additions and 83 deletions

View file

@ -78,5 +78,4 @@ class PublicsController < ApplicationController
return
end
end
end

View file

@ -10,9 +10,9 @@ module Job
@queue = :receive
def self.perform(post_id, recipient_user_ids)
post = Post.find(post_id)
receiver = Postzord::Receiver::LocalPostBatch.new(post, recipient_user_ids)
def self.perform(object_class_string, object_id, recipient_user_ids)
object = object_class_string.constantize.find(object_id)
receiver = Postzord::Receiver::LocalPostBatch.new(object, recipient_user_ids)
receiver.perform!
end
end

View file

@ -91,7 +91,7 @@ class Postzord::Dispatcher
# @param people [Array<Person>] Recipients of the post
def deliver_to_local(people)
return if people.blank? || @object.is_a?(Profile)
if @object.is_a?(Post)
if @object.respond_to?(:persisted?)
batch_deliver_to_local(people)
else
people.each do |person|
@ -104,7 +104,7 @@ class Postzord::Dispatcher
# @param people [Array<Person>] Recipients of the post
def batch_deliver_to_local(people)
ids = people.map{ |p| p.owner_id }
Resque.enqueue(Job::ReceiveLocalBatch, @object.id, ids)
Resque.enqueue(Job::ReceiveLocalBatch, @object.class.to_s, @object.id, ids)
Rails.logger.info("event=push route=local sender=#{@sender.person.diaspora_handle} recipients=#{ids.join(',')} payload_type=#{@object.class}")
end
@ -126,12 +126,6 @@ class Postzord::Dispatcher
end
end
# @param services [Array<User>]
def socket_and_notify_users(users)
notify_users(users)
socket_to_users(users)
end
# @param local_people [Array<People>]
def socket_and_notify_local_users(local_people)
local_users = fetch_local_users(local_people)

View file

@ -1,51 +1,54 @@
module Postzord
module Receiver
class LocalPostBatch
attr_reader :post, :recipient_user_ids, :users
attr_reader :object, :recipient_user_ids, :users
def initialize(post, recipient_user_ids)
@post = post
def initialize(object, recipient_user_ids)
@object = object
@recipient_user_ids = recipient_user_ids
@users = User.where(:id => @recipient_user_ids)
end
def perform!
create_visibilities
socket_to_users if @post.respond_to?(:socket_to_user)
notify_mentioned_users
create_visibilities unless @object.respond_to?(:relayable?)
notify_mentioned_users if @object.respond_to?(:mentions)
socket_to_users if @object.respond_to?(:socket_to_user)
notify_users
end
# Batch import visibilities for the recipients of the given @post
# Batch import visibilities for the recipients of the given @object
# @note performs a bulk insert into mySQL
# @return [void]
def create_visibilities
contacts = Contact.where(:user_id => @recipient_user_ids, :person_id => @post.author_id)
PostVisibility.batch_import(contacts, post)
contacts = Contact.where(:user_id => @recipient_user_ids, :person_id => @object.author_id)
PostVisibility.batch_import(contacts, object)
end
# Notify any mentioned users within the @object's text
# @return [void]
def notify_mentioned_users
@object.mentions.each do |mention|
mention.notify_recipient
end
end
#NOTE(these methods should be in their own module, included in this class)
# Issue websocket requests to all specified recipients
# @return [void]
def socket_to_users
@users.each do |user|
@post.socket_to_user(user)
@object.socket_to_user(user)
end
end
# Notify any mentioned users within the @post's text
# @return [void]
def notify_mentioned_users
@post.mentions.each do |mention|
mention.notify_recipient
end
end
# Notify users of the new post
# Notify users of the new object
# return [void]
def notify_users
return unless @post.respond_to?(:notification_type)
return unless @object.respond_to?(:notification_type)
@users.each do |user|
Notification.notify(user, @post, @post.author)
Notification.notify(user, @object, @object.author)
end
end
end

View file

@ -36,7 +36,7 @@ module Postzord
@object.receive(@object.parent.author.user, @author)
end
# notify everyone who can see the parent object
receiver = Postzord::Receiver::LocalPostBatch.new(nil, self.recipient_user_ids)
receiver = Postzord::Receiver::LocalPostBatch.new(@object, self.recipient_user_ids)
receiver.notify_users
@object
end

View file

@ -55,9 +55,6 @@ describe Postzord::Dispatcher do
end
describe '#post' do
before do
@zord.stub!(:socket_and_notify_users)
end
it 'calls Array#partition on subscribers' do
@zord.instance_variable_set(:@subscribers, @subscribers)
@subscribers.should_receive(:partition).and_return([@remote_people, @local_people])
@ -243,7 +240,7 @@ describe Postzord::Dispatcher do
it 'queues a batch receive' do
local_people = []
local_people << alice.person
Resque.should_receive(:enqueue).with(Job::ReceiveLocalBatch, @sm.id, [alice.id]).once
Resque.should_receive(:enqueue).with(Job::ReceiveLocalBatch, @sm.class.to_s, @sm.id, [alice.id]).once
@mailman.send(:deliver_to_local, local_people)
end
@ -302,30 +299,29 @@ describe Postzord::Dispatcher do
end
end
describe '#socket_and_notify_users' do
it 'should call object#socket_to_user for each local user' do
sc = mock()
SocketsController.should_receive(:new).and_return(sc)
sc.should_receive(:outgoing).with(bob,
@zord.instance_variable_get(:@object),
:aspect_ids => bob.contact_for(alice.person).aspect_memberships.map{|a| postgres? ? a.aspect_id.to_s : a.aspect_id })
@zord.send(:socket_and_notify_users, [bob])
describe '#socket_and_notify_local_users' do
it 'calls notifiy_users' do
@zord.should_receive(:notify_users).with([bob])
@zord.send(:socket_and_notify_local_users, [bob.person])
end
it 'only tries to socket when the object responds to #socket_to_user' do
f = Request.new
f.stub!(:subscribers)
f.stub!(:to_diaspora_xml)
users = [bob]
z = Postzord::Dispatcher.build(alice, f)
z.instance_variable_get(:@object).should_receive(:socket_to_user).once
z.send(:socket_to_users, users)
it 'calls socket_to_users with the object author' do
@zord.should_receive(:socket_to_users).with([bob, @zord.sender])
@zord.send(:socket_and_notify_local_users, [bob.person])
end
end
it 'queues Job::NotifyLocalUsers jobs' do
@zord.instance_variable_get(:@object).should_receive(:socket_to_user).and_return(false)
Resque.should_receive(:enqueue).with(Job::NotifyLocalUsers, [bob.id], @sm.class.to_s, @sm.id, @sm.author.id)
@zord.send(:socket_and_notify_users, [bob])
describe '#notify_users' do
it 'enqueues a NotifyLocalUsers job' do
Resque.should_receive(:enqueue).with(Job::NotifyLocalUsers, [bob.id], @zord.object.class.to_s, @zord.object.id, @zord.object.author.id)
@zord.send(:notify_users, [bob])
end
end
describe '#socket_to_users' do
it 'calls socket_to_user given users' do
@zord.object.should_receive(:socket_to_user).with(bob)
@zord.send(:socket_to_users, [bob])
end
end
end

View file

@ -3,58 +3,55 @@ require File.join(Rails.root, 'lib','postzord', 'receiver', 'local_post_batch')
describe Postzord::Receiver::LocalPostBatch do
before do
@post = Factory(:status_message, :author => alice.person)
@object = Factory(:status_message, :author => alice.person)
@ids = [bob.id]
@receiver = Postzord::Receiver::LocalPostBatch.new(@post, @ids)
end
let(:receiver) { Postzord::Receiver::LocalPostBatch.new(@object, @ids) }
describe '.initialize' do
it 'sets @post, @recipient_user_ids, and @user' do
[:post, :recipient_user_ids, :users].each do |instance_var|
@receiver.send(instance_var).should_not be_nil
[:object, :recipient_user_ids, :users].each do |instance_var|
receiver.send(instance_var).should_not be_nil
end
end
end
describe '#perform!' do
it 'calls .create_visibilities' do
@receiver.should_receive(:create_visibilities)
@receiver.perform!
receiver.should_receive(:create_visibilities)
receiver.perform!
end
it 'sockets to users' do
@receiver.should_receive(:socket_to_users)
@receiver.perform!
receiver.should_receive(:socket_to_users)
receiver.perform!
end
it 'notifies mentioned users' do
@receiver.should_receive(:notify_mentioned_users)
@receiver.perform!
receiver.should_receive(:notify_mentioned_users)
receiver.perform!
end
it 'notifies users' do
@receiver.should_receive(:notify_users)
@receiver.perform!
receiver.should_receive(:notify_users)
receiver.perform!
end
end
describe '#create_visibilities' do
it 'calls Postvisibility.batch_import' do
PostVisibility.should_receive(:batch_import)
@receiver.create_visibilities
receiver.create_visibilities
end
end
describe '#socket_to_users' do
before do
@controller = mock()
SocketsController.stub(:new).and_return(@controller)
it 'sockets to users' do
receiver.users.each do |user|
@object.should_receive(:socket_to_user).with(user)
end
it 'sockets to each user' do
@controller.should_receive(:outgoing).with(bob, @post, instance_of(Hash))
@receiver.socket_to_users
receiver.socket_to_users
end
end
@ -64,14 +61,14 @@ describe Postzord::Receiver::LocalPostBatch do
:author => alice.person,
:text => "Hey @{Bob; #{bob.diaspora_handle}}")
receiver = Postzord::Receiver::LocalPostBatch.new(sm, @ids)
receiver2 = Postzord::Receiver::LocalPostBatch.new(sm, @ids)
Notification.should_receive(:notify).with(bob, anything, alice.person)
receiver.notify_mentioned_users
receiver2.notify_mentioned_users
end
it 'does not call notify person for a non-mentioned person' do
Notification.should_not_receive(:notify)
@receiver.notify_mentioned_users
receiver.notify_mentioned_users
end
end
@ -90,4 +87,23 @@ describe Postzord::Receiver::LocalPostBatch do
receiver.notify_users
end
end
context 'integrates with a comment' do
before do
sm = Factory(:status_message, :author => alice.person)
@object = Factory(:comment, :author => bob.person, :post => sm)
end
it 'calls socket_to_users and notify_users' do
receiver.should_receive(:socket_to_users)
receiver.should_receive(:notify_users)
receiver.perform!
end
it 'does not call create_visibilities and notify_mentioned_users' do
receiver.should_not_receive(:notify_mentioned_users)
receiver.should_not_receive(:create_visibilities)
receiver.perform!
end
end
end