add n_strand to late policy applicator jobs

flag=none
closes EVAL-2885

Limits the number of these jobs for a given root account that can be
running at the same time.

Test Plan:
1. In quick succession, make multiple API requests to create late policies
   for courses. The courses must all be under the same root account.

   POST /api/v1/courses/:id/late_policy

2. In a rails console, check to ensure that the jobs are queued in a
   strand for the root account:

   root_account = Account.find(<id>)

   Delayed::Job.where(
    strand: "LatePolicyApplicator/#{root_account.global_id}"
   ).pluck(:locked_at)

   # only one of the records should show a locked_at. all others should
   # be nil

Change-Id: I35bc43f43ed1e54daff5c7397817b3ba8b8545a6
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/310568
QA-Review: Spencer Olson <solson@instructure.com>
Product-Review: Cameron Ray <cameron.ray@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Derek Williams <derek.williams@instructure.com>
Reviewed-by: Weston Dransfield <wdransfield@instructure.com>
This commit is contained in:
Spencer Olson 2023-02-07 09:58:47 -06:00
parent 3744660842
commit 5174f6df28
2 changed files with 14 additions and 8 deletions

View File

@ -22,16 +22,20 @@ class LatePolicyApplicator
return unless course.published?
return unless course.assignments.published.exists?
new(course).delay_if_production(singleton: "late_policy_applicator:calculator:Course:#{course.global_id}")
.process
new(course).delay_if_production(
singleton: "late_policy_applicator:calculator:Course:#{course.global_id}",
n_strand: ["LatePolicyApplicator", course.root_account.global_id]
).process
end
def self.for_assignment(assignment)
return unless assignment.published? && assignment.points_possible&.positive?
return unless assignment.course
new(assignment.course, [assignment]).delay_if_production(singleton: "late_policy_applicator:calculator:Assignment:#{assignment.global_id}")
.process
new(assignment.course, [assignment]).delay_if_production(
singleton: "late_policy_applicator:calculator:Assignment:#{assignment.global_id}",
n_strand: ["LatePolicyApplicator", assignment.root_account.global_id]
).process
end
def initialize(course, assignments = [])

View File

@ -45,9 +45,10 @@ describe LatePolicyApplicator do
LatePolicyApplicator.for_course(@course)
end
it "kicks off a singleton background job with an identifier based on the course id" do
it "kicks off a singleton-by-course + n_strand-by-root-account background job" do
queueing_args = {
singleton: "late_policy_applicator:calculator:Course:#{@course.global_id}"
singleton: "late_policy_applicator:calculator:Course:#{@course.global_id}",
n_strand: ["LatePolicyApplicator", @course.root_account.global_id]
}
applicator_double = instance_double("LatePolicyApplicator")
@ -108,9 +109,10 @@ describe LatePolicyApplicator do
LatePolicyApplicator.for_assignment(@published_assignment)
end
it "kicks off a singleton background job with an identifier based on the assignment id" do
it "kicks off a singleton-by-assignment + n_strand-by-root-account background job" do
queueing_args = {
singleton: "late_policy_applicator:calculator:Assignment:#{@published_assignment.global_id}"
singleton: "late_policy_applicator:calculator:Assignment:#{@published_assignment.global_id}",
n_strand: ["LatePolicyApplicator", @published_assignment.root_account.global_id]
}
applicator_double = instance_double("LatePolicyApplicator")