-
-
Notifications
You must be signed in to change notification settings - Fork 195
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
114 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# Handles spreading alerts over the day so that we have a more even server load. | ||
module User::SpreadableAlerts | ||
extend ActiveSupport::Concern | ||
|
||
included do | ||
after_initialize :set_alert_times | ||
end | ||
|
||
class_methods do | ||
# Used for default values of last_daily_track_email | ||
def random_time_in_last_day | ||
Time.zone.now - rand(24.hours).seconds | ||
end | ||
|
||
# Alters last_daily_track_email for every user, so alerts will be sent | ||
# spread out fairly evenly throughout the day, balancing load on the server. | ||
# This is intended to be called by hand from the Ruby console. It will mean | ||
# quite a few users may get more than one email alert the day you do it, so | ||
# have a care and run it rarely. | ||
# | ||
# This SQL statement is useful for seeing how spread out users are at the | ||
# moment: | ||
# | ||
# SELECT extract(hour from last_daily_track_email) AS h, COUNT(*) | ||
# FROM users | ||
# GROUP BY extract(hour from last_daily_track_email) | ||
# ORDER BY h; | ||
def spread_alert_times_across_day | ||
find_each do |user| | ||
user.update!(last_daily_track_email: random_time_in_last_day) | ||
end | ||
|
||
nil # so doesn't print all users on console | ||
end | ||
end | ||
|
||
private | ||
|
||
def set_alert_times | ||
return unless new_record? | ||
|
||
# make alert emails go out at a random time for each new user, so | ||
# overall they are spread out throughout the day. | ||
self.last_daily_track_email = self.class.random_time_in_last_day | ||
|
||
# Make daily summary emails go out at a random time for each new user | ||
# too, if it's not already set | ||
self.daily_summary_hour ||= self.class.random_time_in_last_day.hour | ||
self.daily_summary_minute ||= self.class.random_time_in_last_day.min | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
RSpec.shared_examples 'user/spreadable_alerts' do | ||
describe '.random_time_in_last_day' do | ||
subject { described_class.random_time_in_last_day } | ||
|
||
it 'returns a time within the last day' do | ||
expect(subject).to be >= Time.zone.now - 24.hours | ||
expect(subject).to be <= Time.zone.now | ||
end | ||
|
||
it 'returns different times on subsequent calls' do | ||
random_time = described_class.random_time_in_last_day | ||
expect(subject).not_to eq(random_time) | ||
end | ||
end | ||
|
||
describe '.spread_alert_times_across_day' do | ||
# TODO | ||
end | ||
|
||
describe '#daily_summary_time' do | ||
let(:user) do | ||
FactoryBot.create(:user, daily_summary_hour: 7, | ||
daily_summary_minute: 56) | ||
end | ||
|
||
it "returns the hour and minute of the user's daily summary time" do | ||
expected_hash = { hour: 7, min: 56 } | ||
expect(user.daily_summary_time).to eq(expected_hash) | ||
end | ||
end | ||
|
||
describe "setting daily_summary_time on new users" do | ||
let(:user) { FactoryBot.create(:user) } | ||
let(:expected_time) { Time.zone.now.change(hour: 7, min: 57) } | ||
|
||
before do | ||
allow(User). | ||
to receive(:random_time_in_last_day).and_return(expected_time) | ||
end | ||
|
||
it "sets a random hour and minute on initialization" do | ||
expect(user.daily_summary_hour).to eq(7) | ||
expect(user.daily_summary_minute).to eq(57) | ||
end | ||
|
||
it "doesn't override the hour and minute if they're already set" do | ||
user = FactoryBot.create(:user, daily_summary_hour: 9, | ||
daily_summary_minute: 15) | ||
expect(user.daily_summary_hour).to eq(9) | ||
expect(user.daily_summary_minute).to eq(15) | ||
end | ||
|
||
it "doesn't change the the hour and minute once they're set" do | ||
user.save! | ||
expect(user.daily_summary_hour).to eq(7) | ||
expect(user.daily_summary_minute).to eq(57) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters