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

Build queue_url without database when maintenance mode is enabled #58

Merged
merged 1 commit into from
Oct 4, 2017
Merged
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
23 changes: 23 additions & 0 deletions app/models/barbeque/job_queue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,27 @@ class Barbeque::JobQueue < Barbeque::ApplicationRecord
def sqs_queue_name
SQS_NAME_PREFIX + name
end

# Returns queue URL of given name.
# Basically, we should use stored queue URL as the documentation[1] suggests.
# But when the Barbeque's database is temporarily unavailable due to
# scheduled maintenance, we have to build queue URL without the database. The
# maintenance mode is enabled by BARBEQUE_DATABASE_MAINTENANCE and
# AWS_ACCOUNT_ID variable.
# [1]: http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-queue-message-identifiers.html#sqs-general-identifiers
#
# @param name [String] queue name in Barbeque
# @return [String] queue URL of SQS
def self.queue_url_from_name(name)
if database_maintenance_mode?
"https://sqs.#{ENV.fetch('AWS_REGION')}.amazonaws.com/#{ENV.fetch('AWS_ACCOUNT_ID')}/#{SQS_NAME_PREFIX}#{name}"
else
select(:queue_url).find_by!(name: name).queue_url
end
end

def self.database_maintenance_mode?
ENV['BARBEQUE_DATABASE_MAINTENANCE'] == '1' && ENV['AWS_REGION'].present? && ENV['AWS_ACCOUNT_ID'].present?
end
private_class_method :database_maintenance_mode?
end
4 changes: 2 additions & 2 deletions app/services/barbeque/message_enqueuing_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ def initialize(application:, job:, message:, queue: nil)

# @return [String] message_id
def run
queue = Barbeque::JobQueue.find_by!(name: @queue)
queue_url = Barbeque::JobQueue.queue_url_from_name(@queue)
response = Barbeque::MessageEnqueuingService.sqs_client.send_message(
queue_url: queue.queue_url,
queue_url: queue_url,
message_body: build_message.to_json,
)
response.message_id
Expand Down
2 changes: 1 addition & 1 deletion spec/factories/job_queue.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FactoryGirl.define do
factory :job_queue, class: Barbeque::JobQueue do
sequence(:name) { |n| "queue-#{n}" }
sequence(:queue_url) { |n| "https://sqs.ap-northeast-1.amazonaws.com/123456789012/Barbeque-#{n}" }
queue_url { "https://sqs.ap-northeast-1.amazonaws.com/123456789012/Barbeque-#{name}" }
description 'Default queue'
end
end
26 changes: 25 additions & 1 deletion spec/services/message_enqueuing_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
let(:send_message_result) { double('Aws::SQS::Types::SendMessageResult', message_id: message_id) }

before do
allow(Aws::SQS::Client).to receive(:new).and_return(sqs_client)
allow(described_class).to receive(:sqs_client).and_return(sqs_client)
end

it 'enqueues a message whose type is JobExecution' do
Expand Down Expand Up @@ -49,5 +49,29 @@
}.to raise_error(ActiveRecord::RecordNotFound)
end
end

context 'when database is unavailable' do
around do |example|
env = ENV.to_h
ENV['BARBEQUE_DATABASE_MAINTENANCE'] = '1'
ENV['AWS_REGION'] = 'ap-northeast-1'
ENV['AWS_ACCOUNT_ID'] = '123456789012'
example.run
ENV.replace(env)
end

it 'builds queue_url without database' do
expect(sqs_client).to receive(:send_message).with(hash_including(queue_url: job_queue.queue_url)).and_return(send_message_result)
expect(Barbeque::JobQueue).to_not receive(:connection)

result = Barbeque::MessageEnqueuingService.new(
job: job,
queue: job_queue.name,
message: message,
application: application,
).run
expect(result).to eq(message_id)
end
end
end
end