Skip to content

Commit

Permalink
Don't try to enqueue recurring tasks that are undefined
Browse files Browse the repository at this point in the history
For example, if running Mission Control from another app than the one
where the recurring task classes are defined.

Fixes #200
  • Loading branch information
rosa committed Nov 10, 2024
1 parent ba9c1f7 commit 0cd4cb0
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class MissionControl::Jobs::RecurringTasksController < MissionControl::Jobs::ApplicationController
before_action :ensure_supported_recurring_tasks
before_action :set_recurring_task, only: [ :show, :update ]
before_action :ensure_recurring_task_can_be_enqueued, only: :update

def index
@recurring_tasks = MissionControl::Jobs::Current.server.recurring_tasks
Expand All @@ -14,7 +15,7 @@ def update
if (job = @recurring_task.enqueue) && job.successfully_enqueued?
redirect_to application_job_path(@application, job.job_id), notice: "Enqueued recurring task #{@recurring_task.id}"
else
redirect_to application_recurring_task_path(@application, @recurring_task), alert: "Something went wrong enqueuing this recurring task"
redirect_to application_recurring_task_path(@application, @recurring_task.id), alert: "Something went wrong enqueuing this recurring task"
end
end

Expand All @@ -28,4 +29,10 @@ def ensure_supported_recurring_tasks
def set_recurring_task
@recurring_task = MissionControl::Jobs::Current.server.find_recurring_task(params[:id])
end

def ensure_recurring_task_can_be_enqueued
unless @recurring_task.runnable?
redirect_to application_recurring_task_path(@application, @recurring_task.id), alert: "This task can't be enqueued"
end
end
end
4 changes: 4 additions & 0 deletions app/models/mission_control/jobs/recurring_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ def enqueue
queue_adapter.enqueue_recurring_task(id)
end

def runnable?
queue_adapter.can_enqueue_recurring_task?(id)
end

private
attr_reader :queue_adapter
end
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<div class="buttons is-right">
<%= button_to "Run now", application_recurring_task_path(@application, recurring_task.id), class: "button is-warning is-light mr-0", method: :put %>
<% if recurring_task.runnable? %>
<%= button_to "Run now", application_recurring_task_path(@application, recurring_task.id), class: "button is-warning is-light mr-0", method: :put %>
<% end %>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ def enqueue_recurring_task(task_id)
end
end

def can_enqueue_recurring_task?(task_id)
if task = SolidQueue::RecurringTask.find_by(key: task_id)
task.valid?
end
end

private
def recurring_task_attributes_from_solid_queue_recurring_task(task)
{
Expand Down
27 changes: 27 additions & 0 deletions test/controllers/recurring_tasks_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class MissionControl::Jobs::RecurringTasksControllerTest < ActionDispatch::Integ
assert_select "td", "PauseJob"
assert_select "td", "every second"
assert_select "td", /2024-10-30 19:07:1\d\.\d{3}/
assert_select "button", "Run now"
end
end
end
Expand Down Expand Up @@ -53,6 +54,19 @@ class MissionControl::Jobs::RecurringTasksControllerTest < ActionDispatch::Integ
end
end

test "get recurring task with undefined class" do
# simulate recurring task inserted from another app, no validations or callbacks
SolidQueue::RecurringTask.insert({ key: "missing_class_task", class_name: "MissingJob", schedule: "every minute" })
get mission_control_jobs.application_recurring_tasks_url(@application)
assert_response :ok

assert_select "tr.recurring_task", 1
assert_select "td a", "missing_class_task"
assert_select "td", "MissingJob"
assert_select "td", "every minute"
assert_select "button", text: "Run now", count: 0 # Can't be run because the class doesn't exist
end

test "enqueue recurring task successfully" do
schedule_recurring_tasks_async(wait: 0.1.seconds)

Expand All @@ -65,4 +79,17 @@ class MissionControl::Jobs::RecurringTasksControllerTest < ActionDispatch::Integ
assert_equal "PauseJob", job.job_class_name
assert_match /jobs\/#{job.job_id}\?server_id=solid_queue\z/, response.location
end

test "fail to enqueue recurring task with undefined class" do
# simulate recurring task inserted from another app, no validations or callbacks
SolidQueue::RecurringTask.insert({ key: "missing_class_task", class_name: "MissingJob", schedule: "every minute" })

assert_no_difference -> { ActiveJob.jobs.pending.count } do
put mission_control_jobs.application_recurring_task_url(@application, "missing_class_task")
assert_response :redirect

follow_redirect!
assert_select "article.is-danger", /This task can.t be enqueued/
end
end
end

0 comments on commit 0cd4cb0

Please sign in to comment.