Skip to content

Commit f005ba9

Browse files
committed
broadcast policy perf improvements, fixes SD-2130
don't create extra AR objects or incur unnecessary write_attribute taxes (super expensive for serialized columns). this speeds up saving any AR model that has a broadcast policy (whether or not messages are sent), in particular ones having serialized columns (e.g. quiz submissions), since we avoid an unnecessary type cast on each attribute. while it's a little hard to quantify the perf boost we'll see in the app, here is a sampling of numbers we see in the specs: spec/messages : 0:48 -> 0:45 (6.6% reduction) spec/models/a* : 5:59 -> 5:17 (12% reduction) spec/selenium/grades/speedgrader 14:09 -> 13:13 (6.7% reduction), slowest spec went from 0:26 -> 0:19 speed gains in the app will likely be more modest, but performance should noticeably improve in places like the speedgrader (e.g. grade quiz by question) test plan: * specs * regression test of notifications throughout the app, in particular: * discussion topics * assignments * submissions Change-Id: I1ccf6f7f293a35763fde077d612505069823390e Reviewed-on: https://gerrit.instructure.com/102868 Reviewed-by: Landon Wilkins <lwilkins@instructure.com> Reviewed-by: Cody Cutrer <cody@instructure.com> Tested-by: Jenkins QA-Review: Cemal Aktas <caktas@instructure.com> Product-Review: Jon Jensen <jon@instructure.com>
1 parent 879de48 commit f005ba9

17 files changed

Lines changed: 148 additions & 142 deletions

app/controllers/discussion_topics_controller.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -921,16 +921,17 @@ def process_discussion_topic(is_new = false)
921921
model_type = value_to_boolean(params[:is_announcement]) && @context.announcements.temp_record.grants_right?(@current_user, session, :create) ? :announcements : :discussion_topics
922922
if is_new
923923
@topic = @context.send(model_type).build
924+
prior_version = @topic.dup
924925
else
925926
@topic = @context.send(model_type).active.find(params[:id] || params[:topic_id])
927+
prior_version = DiscussionTopic.find(@topic.id)
926928
end
927929

928930
return unless authorized_action(@topic, @current_user, (is_new ? :create : :update))
929931

930932
allowed_fields = @context.is_a?(Group) ? API_ALLOWED_TOPIC_FIELDS_FOR_GROUP : API_ALLOWED_TOPIC_FIELDS
931933
discussion_topic_hash = params.permit(*allowed_fields)
932934

933-
prior_version = @topic.generate_prior_version
934935
process_podcast_parameters(discussion_topic_hash)
935936

936937
if is_new
@@ -982,9 +983,7 @@ def process_discussion_topic(is_new = false)
982983
end
983984

984985
@topic = DiscussionTopic.find(@topic.id)
985-
@topic.just_created = is_new
986-
@topic.prior_version = prior_version
987-
@topic.broadcast_notifications
986+
@topic.broadcast_notifications(prior_version)
988987

989988
render :json => discussion_topic_api_json(@topic, @context, @current_user, session)
990989
else

app/models/assignment.rb

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -621,15 +621,12 @@ def touch_submissions_if_muted_changed
621621
# call this to perform notifications on an Assignment that is not being saved
622622
# (useful when a batch of overrides associated with a new assignment have been saved)
623623
def do_notifications!(prior_version=nil, notify=false)
624-
self.prior_version = prior_version
625-
@broadcasted = false
626624
# TODO: this will blow up if the group_category string is set on the
627625
# previous version, because it gets confused between the db string field
628626
# and the association. one more reason to drop the db column
629-
self.prior_version ||= self.versions.previous(self.current_version.number).try(:model)
630-
self.just_created = self.prior_version.nil?
627+
prior_version ||= self.versions.previous(self.current_version.number).try(:model)
631628
self.notify_of_update = notify || false
632-
broadcast_notifications
629+
broadcast_notifications(prior_version || dup)
633630
remove_assignment_updated_flag
634631
end
635632

app/models/assignment_override.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,9 @@ def notify_change?
285285
self.assignment.context.available? &&
286286
self.assignment.published? &&
287287
self.assignment.created_at < 3.hours.ago &&
288-
(!self.prior_version ||
289-
self.workflow_state != self.prior_version.workflow_state ||
290-
self.due_at_overridden != self.prior_version.due_at_overridden ||
291-
self.due_at_overridden && !Assignment.due_dates_equal?(self.due_at, self.prior_version.due_at))
288+
(workflow_state_changed? ||
289+
due_at_overridden_changed? ||
290+
due_at_overridden && !Assignment.due_dates_equal?(due_at, due_at_was))
292291
end
293292

294293
def set_title_if_needed

app/models/broadcast_policies/assignment_policy.rb

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def should_dispatch_assignment_due_date_changed?
1111
accepting_messages? &&
1212
assignment.changed_in_state(:published, :fields => :due_at) &&
1313
!just_published? &&
14-
!AssignmentPolicy.due_dates_equal?(assignment.due_at, prior_version.due_at) &&
14+
!AssignmentPolicy.due_dates_equal?(assignment.due_at, assignment.due_at_was) &&
1515
created_before(3.hours.ago)
1616
end
1717

@@ -21,14 +21,14 @@ def should_dispatch_assignment_changed?
2121
!assignment.muted? &&
2222
created_before(30.minutes.ago) &&
2323
!just_published? &&
24-
(assignment.points_possible != prior_version.points_possible || assignment.assignment_changed)
24+
(assignment.points_possible_changed? || assignment.assignment_changed)
2525
end
2626

2727
def should_dispatch_assignment_created?
2828
return false unless context_sendable?
2929

3030
published_on_create? || just_published? ||
31-
(prior_version && prior_version.workflow_state != assignment.workflow_state && assignment.published?)
31+
(assignment.workflow_state_changed? && assignment.published?)
3232
end
3333

3434
def should_dispatch_assignment_unmuted?
@@ -45,11 +45,7 @@ def context_sendable?
4545

4646
def accepting_messages?
4747
context_sendable? &&
48-
prior_version
49-
end
50-
51-
def prior_version
52-
assignment.prior_version
48+
!assignment.just_created
5349
end
5450

5551
def created_before(time)

app/models/broadcast_policies/submission_policy.rb

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,12 @@ def just_submitted?
7878
end
7979

8080
def just_submitted_late?
81-
(just_submitted? || prior.try(:submitted_at) != submission.submitted_at)
82-
end
83-
84-
def prior
85-
submission.prior_version
81+
(just_submitted? || submission.submitted_at_changed?)
8682
end
8783

8884
def is_a_resubmission?
89-
prior.submitted_at &&
90-
prior.submitted_at != submission.submitted_at
85+
submission.submitted_at_was &&
86+
submission.submitted_at_changed?
9187
end
9288

9389
def grade_updated?

app/models/broadcast_policies/wiki_page_policy.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def created_before?(time)
2222
def changed_while_published?
2323
wiki_page.published? &&
2424
wiki_page.wiki_page_changed &&
25-
wiki_page.prior_version
25+
!wiki_page.just_created
2626
end
2727
end
2828
end

app/models/conversation_message.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,7 @@ def self.preload_latest(conversation_participants, author=nil)
109109

110110
def after_participants_created_broadcast
111111
conversation_message_participants(true) # reload this association so we get latest data
112-
skip_broadcasts = false
113112
@re_send_message = true
114-
set_broadcast_flags
115113
broadcast_notifications
116114
queue_create_stream_items
117115
generate_user_note!

app/models/course.rb

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -670,19 +670,15 @@ def potential_collaborators
670670
p.to { participating_students_by_date + participating_observers_by_date }
671671
p.whenever { |record|
672672
(record.available? && @grade_weight_changed) ||
673-
(
674-
record.prior_version.present? &&
675-
record.changed_in_state(:available, :fields => :group_weighting_scheme)
676-
)
673+
record.changed_in_state(:available, :fields => :group_weighting_scheme)
677674
}
678675

679676
p.dispatch :new_course
680677
p.to { self.root_account.account_users }
681678
p.whenever { |record|
682679
record.root_account &&
683680
((record.just_created && record.name != Course.default_name) ||
684-
(record.prior_version.present? &&
685-
record.prior_version.name == Course.default_name &&
681+
(record.name_was == Course.default_name &&
686682
record.name != Course.default_name)
687683
)
688684
}

app/models/submission.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1391,7 +1391,7 @@ def <=>(other)
13911391
end
13921392

13931393
def assignment_graded_in_the_last_hour?
1394-
self.prior_version && self.prior_version.graded_at && self.prior_version.graded_at > 1.hour.ago
1394+
graded_at_was && graded_at_was > 1.hour.ago
13951395
end
13961396

13971397
def teacher

gems/broadcast_policy/lib/broadcast_policy.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@
3333
# set_broadcast_policy do
3434
# dispatch :new_assignment
3535
# to { self.students }
36-
# whenever { |record| record.just_created? }
36+
# whenever { |record| record.just_created }
3737
# end
3838
#
3939
# set_broadcast_policy do
4040
# dispatch :assignment_change
4141
# to { self.students }
4242
# whenever { |record|
43-
# record.prior_version != self.version and true
43+
# record.workflow_state_changed?
4444
# # ... some field-wise comparison
4545
# }
4646
# end

0 commit comments

Comments
 (0)