Skip to content

Commit

Permalink
Merge pull request #58 from eagletmt/db-maint
Browse files Browse the repository at this point in the history
Build queue_url without database when maintenance mode is enabled
  • Loading branch information
eagletmt authored Oct 4, 2017
2 parents 33b32af + af6f10c commit e5f8664
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 4 deletions.
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

0 comments on commit e5f8664

Please sign in to comment.