Commit c140dcd8cac306c327a830131f7041b2eb94972b
Committed by
Antonio Terceiro
1 parent
3cab8c3f
Exists in
master
and in
23 other branches
Send mailing in batches
(ActionItem1712)
Showing
5 changed files
with
42 additions
and
41 deletions
Show diff stats
app/models/environment_mailing.rb
| 1 | class EnvironmentMailing < Mailing | 1 | class EnvironmentMailing < Mailing |
| 2 | 2 | ||
| 3 | - def recipient(offset=0) | ||
| 4 | - source.people.first(:order => :id, :offset => offset) | 3 | + def recipients(offset=0, limit=100) |
| 4 | + source.people.all(:order => :id, :offset => offset, :limit => limit, :joins => "LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)", :order => :id, :conditions => { "m.person_id" => nil }) | ||
| 5 | end | 5 | end |
| 6 | 6 | ||
| 7 | def each_recipient | 7 | def each_recipient |
| 8 | offset = 0 | 8 | offset = 0 |
| 9 | - while person = recipient(offset) | ||
| 10 | - unless self.already_sent_mailing_to?(person) | ||
| 11 | - yield person | 9 | + limit = 100 |
| 10 | + while !(people = recipients(offset, limit)).empty? | ||
| 11 | + people.each do |person| | ||
| 12 | + yield person | ||
| 12 | end | 13 | end |
| 13 | - offset = offset + 1 | 14 | + offset = offset + limit |
| 14 | end | 15 | end |
| 15 | end | 16 | end |
| 16 | 17 |
app/models/mailing.rb
| @@ -28,13 +28,7 @@ class Mailing < ActiveRecord::Base | @@ -28,13 +28,7 @@ class Mailing < ActiveRecord::Base | ||
| 28 | '' | 28 | '' |
| 29 | end | 29 | end |
| 30 | 30 | ||
| 31 | - def already_sent_mailing_to?(recipient) | ||
| 32 | - self.mailing_sents.find_by_person_id(recipient.id) | ||
| 33 | - end | ||
| 34 | - | ||
| 35 | def deliver | 31 | def deliver |
| 36 | - offset = 0 | ||
| 37 | - people = [] | ||
| 38 | each_recipient do |recipient| | 32 | each_recipient do |recipient| |
| 39 | Mailing::Sender.deliver_mail(self, recipient.email) | 33 | Mailing::Sender.deliver_mail(self, recipient.email) |
| 40 | self.mailing_sents.create(:person => recipient) | 34 | self.mailing_sents.create(:person => recipient) |
app/models/organization_mailing.rb
| @@ -4,17 +4,18 @@ class OrganizationMailing < Mailing | @@ -4,17 +4,18 @@ class OrganizationMailing < Mailing | ||
| 4 | "#{person.name} <#{source.environment.contact_email}>" | 4 | "#{person.name} <#{source.environment.contact_email}>" |
| 5 | end | 5 | end |
| 6 | 6 | ||
| 7 | - def recipient(offset=0) | ||
| 8 | - source.members.first(:order => :id, :offset => offset) | 7 | + def recipients(offset=0, limit=100) |
| 8 | + source.members.all(:order => :id, :offset => offset, :limit => limit, :joins => "LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)", :order => :id, :conditions => { "m.person_id" => nil }) | ||
| 9 | end | 9 | end |
| 10 | 10 | ||
| 11 | def each_recipient | 11 | def each_recipient |
| 12 | offset = 0 | 12 | offset = 0 |
| 13 | - while person = recipient(offset) | ||
| 14 | - unless self.already_sent_mailing_to?(person) | ||
| 15 | - yield person | 13 | + limit = 50 |
| 14 | + while !(people = recipients(offset, limit)).empty? | ||
| 15 | + people.each do |person| | ||
| 16 | + yield person | ||
| 16 | end | 17 | end |
| 17 | - offset = offset + 1 | 18 | + offset = offset + limit |
| 18 | end | 19 | end |
| 19 | end | 20 | end |
| 20 | 21 |
test/unit/environment_mailing_test.rb
| @@ -7,10 +7,10 @@ class EnvironmentMailingTest < ActiveSupport::TestCase | @@ -7,10 +7,10 @@ class EnvironmentMailingTest < ActiveSupport::TestCase | ||
| 7 | ActionMailer::Base.perform_deliveries = true | 7 | ActionMailer::Base.perform_deliveries = true |
| 8 | ActionMailer::Base.deliveries = [] | 8 | ActionMailer::Base.deliveries = [] |
| 9 | @environment = fast_create(Environment, :name => 'Network') | 9 | @environment = fast_create(Environment, :name => 'Network') |
| 10 | - create_user('user_one', :environment_id => @environment.id) | ||
| 11 | - create_user('user_two', :environment_id => @environment.id) | 10 | + @person_1 = create_user('user_one', :environment_id => @environment.id).person |
| 11 | + @person_2 = create_user('user_two', :environment_id => @environment.id).person | ||
| 12 | end | 12 | end |
| 13 | - attr_reader :environment | 13 | + attr_reader :environment, :person_1, :person_2 |
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | should 'require source_id' do | 16 | should 'require source_id' do |
| @@ -45,53 +45,53 @@ class EnvironmentMailingTest < ActiveSupport::TestCase | @@ -45,53 +45,53 @@ class EnvironmentMailingTest < ActiveSupport::TestCase | ||
| 45 | end | 45 | end |
| 46 | 46 | ||
| 47 | should 'display name and email on generate_from' do | 47 | should 'display name and email on generate_from' do |
| 48 | - person = Person['user_one'] | ||
| 49 | - mailing = EnvironmentMailing.new(:source => environment, :person => person) | 48 | + mailing = EnvironmentMailing.new(:source => environment, :person => person_1) |
| 50 | assert_equal "#{environment.name} <#{environment.contact_email}>", mailing.generate_from | 49 | assert_equal "#{environment.name} <#{environment.contact_email}>", mailing.generate_from |
| 51 | end | 50 | end |
| 52 | 51 | ||
| 53 | should 'deliver mailing to each recipient after create' do | 52 | should 'deliver mailing to each recipient after create' do |
| 54 | - person = Person['user_one'] | ||
| 55 | - mailing = EnvironmentMailing.create(:source => environment, :subject => 'Hello', :body => 'We have some news', :person => person) | 53 | + mailing = EnvironmentMailing.create(:source => environment, :subject => 'Hello', :body => 'We have some news', :person => person_1) |
| 56 | process_delayed_job_queue | 54 | process_delayed_job_queue |
| 57 | assert_equal 2, ActionMailer::Base.deliveries.count | 55 | assert_equal 2, ActionMailer::Base.deliveries.count |
| 58 | end | 56 | end |
| 59 | 57 | ||
| 60 | should 'create mailing sent to each recipient after delivering mailing' do | 58 | should 'create mailing sent to each recipient after delivering mailing' do |
| 61 | - person = Person['user_one'] | ||
| 62 | - mailing = EnvironmentMailing.create(:source => environment, :subject => 'Hello', :body => 'We have some news', :person => person) | 59 | + mailing = EnvironmentMailing.create(:source => environment, :subject => 'Hello', :body => 'We have some news', :person => person_1) |
| 63 | assert_difference MailingSent, :count, 2 do | 60 | assert_difference MailingSent, :count, 2 do |
| 64 | process_delayed_job_queue | 61 | process_delayed_job_queue |
| 65 | end | 62 | end |
| 66 | end | 63 | end |
| 67 | 64 | ||
| 68 | should 'change locale according to the mailing locale' do | 65 | should 'change locale according to the mailing locale' do |
| 69 | - person = Person['user_one'] | ||
| 70 | - mailing = EnvironmentMailing.create(:source => environment, :subject => 'Hello', :body => 'We have some news', :locale => 'pt', :person => person) | 66 | + mailing = EnvironmentMailing.create(:source => environment, :subject => 'Hello', :body => 'We have some news', :locale => 'pt', :person => person_1) |
| 71 | Noosfero.expects(:with_locale).with('pt') | 67 | Noosfero.expects(:with_locale).with('pt') |
| 72 | process_delayed_job_queue | 68 | process_delayed_job_queue |
| 73 | end | 69 | end |
| 74 | 70 | ||
| 75 | - should 'return recipient' do | ||
| 76 | - mailing = EnvironmentMailing.new(:source => environment) | ||
| 77 | - assert_equal Person['user_one'], mailing.recipient | 71 | + should 'return recipients' do |
| 72 | + mailing = EnvironmentMailing.create(:source => environment, :subject => 'Hello', :body => 'We have some news', :locale => 'pt', :person => person_1) | ||
| 73 | + assert_equal [person_1, person_2], mailing.recipients | ||
| 74 | + end | ||
| 75 | + | ||
| 76 | + should 'return recipients according to limit' do | ||
| 77 | + mailing = EnvironmentMailing.create(:source => environment, :subject => 'Hello', :body => 'We have some news', :locale => 'pt', :person => person_1) | ||
| 78 | + assert_equal [person_1], mailing.recipients(0, 1) | ||
| 78 | end | 79 | end |
| 79 | 80 | ||
| 80 | should 'return true if already sent mailing to a recipient' do | 81 | should 'return true if already sent mailing to a recipient' do |
| 81 | - person = Person['user_one'] | ||
| 82 | - mailing = EnvironmentMailing.create(:source => environment, :subject => 'Hello', :body => 'We have some news', :person => person) | 82 | + mailing = EnvironmentMailing.create(:source => environment, :subject => 'Hello', :body => 'We have some news', :person => person_1) |
| 83 | process_delayed_job_queue | 83 | process_delayed_job_queue |
| 84 | 84 | ||
| 85 | - assert mailing.already_sent_mailing_to?(person) | 85 | + assert mailing.mailing_sents.find_by_person_id(person_1.id) |
| 86 | end | 86 | end |
| 87 | 87 | ||
| 88 | should 'return false if did not sent mailing to a recipient' do | 88 | should 'return false if did not sent mailing to a recipient' do |
| 89 | recipient = fast_create(Person) | 89 | recipient = fast_create(Person) |
| 90 | person = Person['user_one'] | 90 | person = Person['user_one'] |
| 91 | - mailing = EnvironmentMailing.create(:source => environment, :subject => 'Hello', :body => 'We have some news', :person => person) | 91 | + mailing = EnvironmentMailing.create(:source => environment, :subject => 'Hello', :body => 'We have some news', :person => person_1) |
| 92 | process_delayed_job_queue | 92 | process_delayed_job_queue |
| 93 | 93 | ||
| 94 | - assert !mailing.already_sent_mailing_to?(recipient) | 94 | + assert !mailing.mailing_sents.find_by_person_id(recipient.id) |
| 95 | end | 95 | end |
| 96 | 96 | ||
| 97 | end | 97 | end |
test/unit/organization_mailing_test.rb
| @@ -87,15 +87,20 @@ class OrganizationMailingTest < ActiveSupport::TestCase | @@ -87,15 +87,20 @@ class OrganizationMailingTest < ActiveSupport::TestCase | ||
| 87 | end | 87 | end |
| 88 | 88 | ||
| 89 | should 'return recipient' do | 89 | should 'return recipient' do |
| 90 | - mailing = OrganizationMailing.new(:source => community) | ||
| 91 | - assert_equal Person['user_one'], mailing.recipient | 90 | + mailing = OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person) |
| 91 | + assert_equal [Person['user_one'], Person['user_two']], mailing.recipients | ||
| 92 | + end | ||
| 93 | + | ||
| 94 | + should 'return recipients according to limit' do | ||
| 95 | + mailing = OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person) | ||
| 96 | + assert_equal [Person['user_one']], mailing.recipients(0, 1) | ||
| 92 | end | 97 | end |
| 93 | 98 | ||
| 94 | should 'return true if already sent mailing to a recipient' do | 99 | should 'return true if already sent mailing to a recipient' do |
| 95 | member = Person['user_one'] | 100 | member = Person['user_one'] |
| 96 | mailing = OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person) | 101 | mailing = OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person) |
| 97 | process_delayed_job_queue | 102 | process_delayed_job_queue |
| 98 | - assert mailing.already_sent_mailing_to?(member) | 103 | + assert mailing.mailing_sents.find_by_person_id(member.id) |
| 99 | end | 104 | end |
| 100 | 105 | ||
| 101 | should 'return false if did not sent mailing to a recipient' do | 106 | should 'return false if did not sent mailing to a recipient' do |
| @@ -103,7 +108,7 @@ class OrganizationMailingTest < ActiveSupport::TestCase | @@ -103,7 +108,7 @@ class OrganizationMailingTest < ActiveSupport::TestCase | ||
| 103 | mailing = OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person) | 108 | mailing = OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person) |
| 104 | process_delayed_job_queue | 109 | process_delayed_job_queue |
| 105 | 110 | ||
| 106 | - assert !mailing.already_sent_mailing_to?(recipient) | 111 | + assert !mailing.mailing_sents.find_by_person_id(recipient.id) |
| 107 | end | 112 | end |
| 108 | 113 | ||
| 109 | protected | 114 | protected |