Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: GoodJob::AdvisoryLockable::RecordAlreadyAdvisoryLockedError (MAYBE-RAILS-DK) #1797

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions app/controllers/good_job/jobs_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
module GoodJob
class JobsController < GoodJob::ApplicationController
rescue_from GoodJob::AdvisoryLockable::RecordAlreadyAdvisoryLockedError, with: :handle_record_already_locked

before_action :set_job, only: [:show, :destroy, :discard, :retry, :reschedule]

Check failure on line 5 in app/controllers/good_job/jobs_controller.rb

View workflow job for this annotation

GitHub Actions / ci / lint

Layout/SpaceInsideArrayLiteralBrackets: Use space inside array brackets.

Check failure on line 5 in app/controllers/good_job/jobs_controller.rb

View workflow job for this annotation

GitHub Actions / ci / lint

Layout/SpaceInsideArrayLiteralBrackets: Use space inside array brackets.
after_action :enable_polling, only: [:index]

Check failure on line 6 in app/controllers/good_job/jobs_controller.rb

View workflow job for this annotation

GitHub Actions / ci / lint

Layout/SpaceInsideArrayLiteralBrackets: Use space inside array brackets.

Check failure on line 6 in app/controllers/good_job/jobs_controller.rb

View workflow job for this annotation

GitHub Actions / ci / lint

Layout/SpaceInsideArrayLiteralBrackets: Use space inside array brackets.

def index
@jobs = Job.all
@jobs = @jobs.where(active_job_id: params[:active_job_id]) if params[:active_job_id].present?
@jobs = @jobs.where(queue_name: params[:queue_name]) if params[:queue_name].present?
@jobs = @jobs.includes_advisory_locks

Check failure on line 13 in app/controllers/good_job/jobs_controller.rb

View workflow job for this annotation

GitHub Actions / ci / lint

Layout/TrailingWhitespace: Trailing whitespace detected.
respond_to do |format|
format.html
format.json { render json: @jobs }
end
end

def show
respond_to do |format|
format.html
format.json { render json: @job }
end
end

def destroy
@job.destroy
respond_to do |format|
format.html { redirect_to good_job_jobs_path, notice: "Job was successfully destroyed." }
format.json { head :no_content }
end
end

def discard
@job.discard!
respond_to do |format|
format.html { redirect_to good_job_jobs_path, notice: "Job was successfully discarded." }
format.json { head :no_content }
end
end

def retry
@job.retry!
respond_to do |format|
format.html { redirect_to good_job_jobs_path, notice: "Job was successfully retried." }
format.json { head :no_content }
end
end

def reschedule
@job.reschedule!
respond_to do |format|
format.html { redirect_to good_job_jobs_path, notice: "Job was successfully rescheduled." }
format.json { head :no_content }
end
end

private

def set_job

Check failure on line 61 in app/controllers/good_job/jobs_controller.rb

View workflow job for this annotation

GitHub Actions / ci / lint

Layout/IndentationWidth: Use 2 (not 0) spaces for indented_internal_methods indentation.
@job = Job.find(params[:id])
end

def enable_polling
@polling_enabled = true
end

def handle_record_already_locked
respond_to do |format|
format.html {

Check failure on line 71 in app/controllers/good_job/jobs_controller.rb

View workflow job for this annotation

GitHub Actions / ci / lint

Layout/TrailingWhitespace: Trailing whitespace detected.
flash[:alert] = "This job is already being processed or locked."
redirect_to good_job_jobs_path
}
format.json {

Check failure on line 75 in app/controllers/good_job/jobs_controller.rb

View workflow job for this annotation

GitHub Actions / ci / lint

Layout/TrailingWhitespace: Trailing whitespace detected.
render json: { error: "Job is locked" }, status: :conflict

Check failure on line 76 in app/controllers/good_job/jobs_controller.rb

View workflow job for this annotation

GitHub Actions / ci / lint

Layout/TrailingWhitespace: Trailing whitespace detected.
}
end
end
end
end
60 changes: 60 additions & 0 deletions spec/controllers/good_job/jobs_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require 'rails_helper'

RSpec.describe GoodJob::JobsController, type: :controller do
let(:user) { create(:user, :super_admin) }

Check failure on line 5 in spec/controllers/good_job/jobs_controller_spec.rb

View workflow job for this annotation

GitHub Actions / ci / lint

Layout/TrailingWhitespace: Trailing whitespace detected.
before do
sign_in(user)
end

describe "GET #show" do
let(:job) { create(:good_job_job) }

context "when the job is available" do
it "returns successful response" do
get :show, params: { id: job.id }
expect(response).to be_successful
end
end

context "when the job is already advisory locked" do
before do
allow_any_instance_of(GoodJob::Job).to receive(:advisory_locked?).and_return(true)
allow_any_instance_of(GoodJob::Job).to receive(:perform).and_raise(GoodJob::AdvisoryLockable::RecordAlreadyAdvisoryLockedError)
end

it "redirects with an alert message" do
get :show, params: { id: job.id }
expect(response).to redirect_to(good_job_jobs_path)
expect(flash[:alert]).to eq("This job is already being processed or locked.")
end

it "returns conflict status for JSON requests" do
get :show, params: { id: job.id }, format: :json
expect(response).to have_http_status(:conflict)
expect(JSON.parse(response.body)).to eq({ "error" => "Job is locked" })
end
end
end

describe "POST #retry" do
let(:job) { create(:good_job_job) }

context "when the job is already advisory locked" do
before do
allow_any_instance_of(GoodJob::Job).to receive(:retry!).and_raise(GoodJob::AdvisoryLockable::RecordAlreadyAdvisoryLockedError)
end

it "redirects with an alert message" do
post :retry, params: { id: job.id }
expect(response).to redirect_to(good_job_jobs_path)
expect(flash[:alert]).to eq("This job is already being processed or locked.")
end

it "returns conflict status for JSON requests" do
post :retry, params: { id: job.id }, format: :json
expect(response).to have_http_status(:conflict)
end
end
end
end
33 changes: 33 additions & 0 deletions spec/features/good_job/jobs_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
require 'rails_helper'

RSpec.describe "GoodJob Jobs Management", type: :feature do
let(:user) { create(:user, :super_admin) }

before do
sign_in(user)
end

describe "handling locked jobs" do
let!(:job) { create(:good_job_job) }

scenario "attempting to view a locked job" do
allow_any_instance_of(GoodJob::Job).to receive(:advisory_locked?).and_return(true)
allow_any_instance_of(GoodJob::Job).to receive(:perform).and_raise(GoodJob::AdvisoryLockable::RecordAlreadyAdvisoryLockedError)

visit good_job_job_path(job)

expect(page).to have_content("This job is already being processed or locked.")
expect(current_path).to eq(good_job_jobs_path)
end

scenario "attempting to retry a locked job" do
allow_any_instance_of(GoodJob::Job).to receive(:retry!).and_raise(GoodJob::AdvisoryLockable::RecordAlreadyAdvisoryLockedError)

visit good_job_jobs_path
click_link "Retry"

expect(page).to have_content("This job is already being processed or locked.")
expect(current_path).to eq(good_job_jobs_path)
end
end
end
Loading