Skip to content

Commit

Permalink
Merge pull request #94 from alphagov/sigterm
Browse files Browse the repository at this point in the history
Fix broken handling of signals
  • Loading branch information
csutter authored Sep 28, 2023
2 parents d735c47 + e53ae0d commit fe8043b
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 14 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Unreleased

* Drop support for Ruby 2.7.
- Drop support for Ruby 2.7.
- Fix ability to handle system signals, and report non-`SIGTERM` errors to `GovukError`

# 4.1.0

Expand Down Expand Up @@ -36,7 +37,7 @@
# 3.2.0

- Add batch process capabilities
- Refactor `process_chain` to `message_consumer`
- Refactor `process_chain` to `message_consumer`

# 3.1.0

Expand Down
7 changes: 4 additions & 3 deletions lib/govuk_message_queue_consumer/consumer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,16 @@ def run(subscribe_opts: {})
@statsd_client.increment("#{@queue_name}.started")
message_consumer.process(message)
@statsd_client.increment("#{@queue_name}.#{message.status}")
rescue SignalException => e
@logger.error "SignalException in processor: \n\n #{e.class}: #{e.message}\n\n#{e.backtrace.join("\n")}"
exit(1) # Ensure rabbitmq requeues outstanding messages
rescue StandardError => e
@statsd_client.increment("#{@queue_name}.uncaught_exception")
GovukError.notify(e) if defined?(GovukError)
@logger.error "Uncaught exception in processor: \n\n #{e.class}: #{e.message}\n\n#{e.backtrace.join("\n")}"
exit(1) # Ensure rabbitmq requeues outstanding messages
end
rescue SignalException => e
GovukError.notify(e) if defined?(GovukError) && e.message != "SIGTERM"

exit
end

private
Expand Down
40 changes: 31 additions & 9 deletions spec/govuk_message_queue_consumer/consumer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,23 @@
let(:client_processor) { instance_double("Client::Processor") }

describe "#run" do
it "doesn't create the queue" do
stubs = create_bunny_stubs
channel = stubs.channel
let(:stubs) { create_bunny_stubs }
let(:channel) { stubs.channel }
let(:queue) { stubs.queue }

it "doesn't create the queue" do
expect(channel).to receive(:queue).with("some-queue", { no_declare: true })

described_class.new(queue_name: "some-queue", processor: client_processor, rabbitmq_connection: stubs.connection, logger: logger).run
end

it "doesn't bind the queue" do
stubs = create_bunny_stubs
queue = stubs.queue

expect(queue).not_to receive(:bind)

described_class.new(queue_name: "some-queue", processor: client_processor, rabbitmq_connection: stubs.connection, logger: logger).run
end

it "calls the heartbeat processor when subscribing to messages" do
stubs = create_bunny_stubs
queue = stubs.queue

expect(queue).to receive(:subscribe).and_yield(:delivery_info_object, :headers, "payload")
heartbeat_processor_stub = instance_double(GovukMessageQueueConsumer::HeartbeatProcessor)
allow(GovukMessageQueueConsumer::HeartbeatProcessor).to receive(:new).and_return(heartbeat_processor_stub)
Expand All @@ -38,5 +33,32 @@

described_class.new(queue_name: "some-queue", processor: client_processor, rabbitmq_connection: stubs.connection, logger: logger).run
end

context "when a SignalException is raised" do
before do
allow(queue).to receive(:subscribe).and_raise(error)
end

context "and the signal is a SIGTERM" do
let(:error) { SignalException.new("SIGTERM") }

it "gracefully exits" do
expect { described_class.new(queue_name: "some-queue", processor: client_processor, rabbitmq_connection: stubs.connection, logger: logger).run }.to raise_error(SystemExit)
end
end

context "and the signal is an unexpected one" do
let(:error) { SignalException.new("SIGWINCH") }

before do
stub_const("GovukError", double(notify: nil)) # rubocop:disable RSpec/VerifiedDoubles
end

it "gracefully exits after notifying GovukError" do
expect(GovukError).to receive(:notify).with(error)
expect { described_class.new(queue_name: "some-queue", processor: client_processor, rabbitmq_connection: stubs.connection, logger: logger).run }.to raise_error(SystemExit)
end
end
end
end
end

0 comments on commit fe8043b

Please sign in to comment.