From 5e433d893dfdb9aec782861b2527433b0b4a31c1 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sun, 12 Oct 2025 16:43:20 +1100 Subject: [PATCH 1/3] remove delete all requeue all --- lib/outboxer/web.rb | 97 ------------------- lib/outboxer/web/views/messages.erb | 93 ++++++++++-------- .../outboxer/web/messages/delete_all_spec.rb | 94 ------------------ .../outboxer/web/messages/requeue_all_spec.rb | 89 ----------------- 4 files changed, 53 insertions(+), 320 deletions(-) delete mode 100644 spec/lib/outboxer/web/messages/delete_all_spec.rb delete mode 100644 spec/lib/outboxer/web/messages/requeue_all_spec.rb diff --git a/lib/outboxer/web.rb b/lib/outboxer/web.rb index c0cd37be..c0394447 100755 --- a/lib/outboxer/web.rb +++ b/lib/outboxer/web.rb @@ -570,103 +570,6 @@ def normalise_query_string(status: Message::LIST_STATUS_DEFAULT, redirect to("/messages#{normalised_query_string}") end - post "/messages/requeue_all" do - denormalised_query_params = denormalise_query_params( - status: params[:status], - sort: params[:sort], - order: params[:order], - page: params[:page], - per_page: params[:per_page], - time_zone: params[:time_zone]) - - status = denormalised_query_params[:status] - raise ArgumentError, "status is required" if status.nil? - - requeued_count = 0 - failed_count = 0 - - Outboxer::Message.each_id(status: status) do |id| - Outboxer::Message.requeue(id: id) - requeued_count += 1 - rescue StandardError => error - settings.logger.error( - "[Outboxer::Web] Failed to requeue message id=#{id}\n" \ - "error_class=#{error.class}\n" \ - "error_message=#{error.message.inspect}" - ) - failed_count += 1 - end - - flashes = {} - if requeued_count.positive? - flashes[:success] = "Requeued #{pluralise(requeued_count, "message")}" - end - - if failed_count.positive? - flashes[:danger] = "Requeue failed for #{pluralise(failed_count, "message")}" - end - - normalised_query_string = normalise_query_string( - status: denormalised_query_params[:status], - sort: denormalised_query_params[:sort], - order: denormalised_query_params[:order], - page: denormalised_query_params[:page], - per_page: denormalised_query_params[:per_page], - time_zone: denormalised_query_params[:time_zone], - flash: flashes - ) - - redirect to("/messages#{normalised_query_string}") - end - - post "/messages/delete_all" do - denormalised_query_params = denormalise_query_params( - status: params[:status], - sort: params[:sort], - order: params[:order], - page: params[:page], - per_page: params[:per_page], - time_zone: params[:time_zone] - ) - - status = denormalised_query_params[:status] - deleted_count = 0 - failed_count = 0 - - Outboxer::Message.each_id(status: status) do |id| - Outboxer::Message.delete(id: id) - deleted_count += 1 - rescue StandardError => error - settings.logger.error( - "[Outboxer::Web] Failed to delete message id=#{id}\n" \ - "error_class=#{error.class}\n" \ - "error_message=#{error.message.inspect}" - ) - failed_count += 1 - end - - flashes = {} - if deleted_count.positive? - flashes[:success] = "Deleted #{pluralise(deleted_count, "message")}" - end - - if failed_count.positive? - flashes[:danger] = "Delete failed for #{pluralise(failed_count, "message")}" - end - - normalised_query_string = normalise_query_string( - status: denormalised_query_params[:status], - sort: denormalised_query_params[:sort], - order: denormalised_query_params[:order], - page: denormalised_query_params[:page], - per_page: denormalised_query_params[:per_page], - time_zone: denormalised_query_params[:time_zone], - flash: flashes - ) - - redirect to("/messages#{normalised_query_string}") - end - post "/messages/update_per_page" do denormalised_query_params = denormalise_query_params( status: params[:status], diff --git a/lib/outboxer/web/views/messages.erb b/lib/outboxer/web/views/messages.erb index dbc2b107..88cb3060 100644 --- a/lib/outboxer/web/views/messages.erb +++ b/lib/outboxer/web/views/messages.erb @@ -11,51 +11,64 @@
-
" - method="post" class="me-2"> - - <% normalised_query_params.each do |key, param| %> - - <% end %> - -
-
" method="post"> - - <% normalised_query_params.each do |key, param| %> - - <% end %> - -
+ +
" method="post" class="me-2"> + <% normalised_query_params.each do |key, param| %> + + <% end %> + + <% messages.each do |message| %> + + <% end %> + +
+ + +
" method="post"> + <% normalised_query_params.each do |key, param| %> + + <% end %> + + <% messages.each do |message| %> + + <% end %> + +
- <% if Outboxer::Message.can_requeue?(status: denormalised_query_params[:status]) %> -
" method="post" class="mb-2"> - - <% normalised_query_params.each do |key, param| %> - - <% end %> - - -
+ <% if Outboxer::Message.can_requeue?(status: denormalised_query_params[:status]) %> +
" method="post" class="mb-2"> + <% normalised_query_params.each do |key, param| %> + <% end %> - " method="post"> - - <% normalised_query_params.each do |key, param| %> - - <% end %> - + + <% messages.each do |message| %> + + <% end %> +
+ <% end %> + +
" method="post"> + <% normalised_query_params.each do |key, param| %> + + <% end %> + + <% messages.each do |message| %> + + <% end %> + +
diff --git a/spec/lib/outboxer/web/messages/delete_all_spec.rb b/spec/lib/outboxer/web/messages/delete_all_spec.rb deleted file mode 100644 index 9cfb1629..00000000 --- a/spec/lib/outboxer/web/messages/delete_all_spec.rb +++ /dev/null @@ -1,94 +0,0 @@ -require "rails_helper" - -require_relative "../../../../../lib/outboxer/web" - -RSpec.describe "POST /messages/delete_all", type: :request do - include Rack::Test::Methods - - def app - Outboxer::Web - end - - let(:messageable_1) { double("Event", id: 1, class: double(name: "Event")) } - let(:message_1_id) { Outboxer::Message.queue(messageable: messageable_1)[:id] } - let!(:message_1) { Outboxer::Models::Message.find(message_1_id) } - - let(:messageable_2) { double("Event", id: 2, class: double(name: "Event")) } - let(:message_2_id) { Outboxer::Message.queue(messageable: messageable_2)[:id] } - let!(:message_2) { Outboxer::Models::Message.find(message_2_id) } - - let(:messageable_3) { double("Event", id: 3, class: double(name: "Event")) } - let(:message_3_id) { Outboxer::Message.queue(messageable: messageable_3)[:id] } - let!(:message_3) { Outboxer::Models::Message.find(message_3_id) } - - context "when no status provided" do - before do - header "Host", "localhost" - - post "/messages/delete_all", { - page: 1, - per_page: 10, - sort: :queued_at, - order: :desc, - time_zone: "Australia/Sydney" - } - - follow_redirect! - end - - it "deletes all messages" do - expect(Outboxer::Models::Message.count).to eq(0) - end - - it "redirects to /messages" do - expect(last_response).to be_ok - expect(last_request.url).to include( - "messages?sort=queued_at&order=desc&per_page=10&time_zone=Australia%2FSydney") - end - - it "flashes deleted messages count" do - expected_flash = URI.encode_www_form_component("success:Deleted 3 message") - expect(last_request.url).to include("flash=#{expected_flash}") - end - end - - context "when failed status provided" do - before do - message_2.update!(status: Outboxer::Message::Status::PUBLISHING) - message_3.update!(status: Outboxer::Message::Status::FAILED) - - header "Host", "localhost" - - post "/messages/delete_all", { - status: :failed, - page: 1, - per_page: 10, - sort: :queued_at, - order: :desc, - time_zone: "Australia/Sydney" - } - - follow_redirect! - end - - it "deletes failed messages" do - expect(Outboxer::Models::Message.failed.count).to eq(0) - end - - it "does not delete other messages" do - expect(Outboxer::Models::Message.queued.count).to eq(1) - expect(Outboxer::Models::Message.publishing.count).to eq(1) - end - - it "redirects to /messages" do - expect(last_response).to be_ok - expect(last_request.url).to include( - "messages?status=failed&sort=queued_at&order=desc&per_page=10&time_zone=Australia%2FSydney") - end - - it "flashes deleted messages count" do - expected_flash = URI.encode_www_form_component("success:Deleted 1 message") - expect(last_request.url).to include("flash=#{expected_flash}") - end - end -end diff --git a/spec/lib/outboxer/web/messages/requeue_all_spec.rb b/spec/lib/outboxer/web/messages/requeue_all_spec.rb deleted file mode 100644 index 0b5d9b53..00000000 --- a/spec/lib/outboxer/web/messages/requeue_all_spec.rb +++ /dev/null @@ -1,89 +0,0 @@ -require "rails_helper" - -require_relative "../../../../../lib/outboxer/web" - -RSpec.describe "POST /messages/requeue_all", type: :request do - include Rack::Test::Methods - - def app - Outboxer::Web - end - - let(:messageable_1) { double("Event", id: 1, class: double(name: "Event")) } - let(:message_1_id) { Outboxer::Message.queue(messageable: messageable_1)[:id] } - let!(:message_1) { Outboxer::Models::Message.find(message_1_id) } - - let(:messageable_2) { double("Event", id: 2, class: double(name: "Event")) } - let(:message_2_id) { Outboxer::Message.queue(messageable: messageable_2)[:id] } - let!(:message_2) { Outboxer::Models::Message.find(message_2_id) } - - let(:messageable_3) { double("Event", id: 3, class: double(name: "Event")) } - let(:message_3_id) { Outboxer::Message.queue(messageable: messageable_3)[:id] } - let!(:message_3) { Outboxer::Models::Message.find(message_3_id) } - - context "when no status provided" do - before do - message_2.update!(status: Outboxer::Message::Status::PUBLISHING) - message_3.update!(status: Outboxer::Message::Status::FAILED) - - header "Host", "localhost" - - post "/messages/requeue_all", { - page: 1, - per_page: 10, - sort: :queued_at, - order: :desc, - time_zone: "Australia/Sydney" - } - end - - it "responds with 500 internal server error" do - expect(last_response.status).to eq(500) - end - - it "does not requeue messages" do - expect(Outboxer::Models::Message.queued.count).to eq(1) - expect(Outboxer::Models::Message.publishing.count).to eq(1) - expect(Outboxer::Models::Message.failed.count).to eq(1) - end - end - - context "when failed status provided" do - before do - message_2.update!(status: Outboxer::Message::Status::PUBLISHING) - message_3.update!(status: Outboxer::Message::Status::FAILED) - - header "Host", "localhost" - - post "/messages/requeue_all", { - status: :failed, - page: 1, - per_page: 10, - sort: :queued_at, - order: :desc, - time_zone: "Australia/Sydney" - } - - follow_redirect! - end - - it "requeues messages" do - expect(Outboxer::Models::Message.queued.count).to eq(2) - end - - it "does not requeue publishing messages" do - expect(Outboxer::Models::Message.publishing.count).to eq(1) - end - - it "redirects to /messages" do - expect(last_response).to be_ok - expect(last_request.url).to include( - "messages?status=failed&sort=queued_at&order=desc&per_page=10&time_zone=Australia%2FSydney") - end - - it "flashes requeued messages count" do - expected_flash = URI.encode_www_form_component("success:Requeued 1 message") - expect(last_request.url).to include("flash=#{expected_flash}") - end - end -end From c2570e1dcf46b8eaf6d75a01878f286d29c52309 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sun, 12 Oct 2025 16:45:36 +1100 Subject: [PATCH 2/3] add delete page --- lib/outboxer/message.rb | 7 ---- .../outboxer/message/can_requeue_all_spec.rb | 39 ------------------- 2 files changed, 46 deletions(-) delete mode 100644 spec/lib/outboxer/message/can_requeue_all_spec.rb diff --git a/lib/outboxer/message.rb b/lib/outboxer/message.rb index d50a6e03..81d04dfe 100644 --- a/lib/outboxer/message.rb +++ b/lib/outboxer/message.rb @@ -682,13 +682,6 @@ def list(status: LIST_STATUS_DEFAULT, } end - # Checks if all messages with a specific status can be requeued. - # @param status [Symbol] the status to check for requeue eligibility. - # @return [Boolean] true if messages with the given status can be requeued, false otherwise. - def can_requeue_all?(status:) - REQUEUE_STATUSES.include?(status&.to_sym) - end - # Retrieves and calculates metrics related to message statuses, including counts and totals. # Latency and throughput are placeholders (0) until partitioned metrics tables are implemented. # @return [Hash] detailed metrics across various message statuses. diff --git a/spec/lib/outboxer/message/can_requeue_all_spec.rb b/spec/lib/outboxer/message/can_requeue_all_spec.rb deleted file mode 100644 index d7a58b4b..00000000 --- a/spec/lib/outboxer/message/can_requeue_all_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -require "rails_helper" - -module Outboxer - RSpec.describe Message do - describe ".can_requeue?" do - let!(:message_1) { create(:outboxer_message, :queued) } - let!(:message_2) { create(:outboxer_message, :queued) } - let!(:message_3) { create(:outboxer_message, :failed) } - let!(:message_4) { create(:outboxer_message, :failed) } - let!(:message_5) { create(:outboxer_message, :publishing) } - - context "when status is queued" do - it "returns true" do - expect(Message.can_requeue?(status: Message::Status::QUEUED)).to eq false - end - end - - context "when status is publishing" do - it "returns true" do - expect( - Message.can_requeue?(status: Message::Status::PUBLISHING)).to eq true - end - end - - context "when status is failed" do - it "returns true" do - expect( - Message.can_requeue?(status: Message::Status::FAILED)).to eq true - end - end - - context "when status is nil" do - it "returns false" do - expect(Message.can_requeue?(status: nil)).to eq false - end - end - end - end -end From 3c85e100a34f919ca0a1d4c9ff816879c121cdd5 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sun, 12 Oct 2025 16:47:38 +1100 Subject: [PATCH 3/3] remove unnecessary code --- lib/outboxer/message.rb | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/lib/outboxer/message.rb b/lib/outboxer/message.rb index 81d04dfe..958b0aa7 100644 --- a/lib/outboxer/message.rb +++ b/lib/outboxer/message.rb @@ -476,37 +476,6 @@ def find_by_id(id:) end end - # Iterates or returns an enumerator of message ids filtered by status and time. - # - # @param status [Symbol, nil] optional filter for message status; nil = all - # @param older_than [Time, nil] optional cutoff; only messages updated before this time - # @param batch_size [Integer] number of records to process per batch (default: 1000) - # @yield [id] yields each message id if a block is given - # @return [Enumerator] enumerator of ids if no block given - # - # @example - # # Delete all failed messages - # Outboxer::Message.each_id(status: :failed, older_than: Time.now.utc) do |id| - # Outboxer::Message.delete(id: id, time: Time) - # end - def each_id(status: nil, older_than: nil, batch_size: 1_000, &block) - scope = Models::Message.all - scope = scope.where(status: status) unless status.nil? - scope = scope.where("updated_at < ?", older_than) if older_than - - enumerator = Enumerator.new do |yielder| - scope.select(:id).in_batches(of: batch_size) do |relation| - relation.pluck(:id).each { |id| yielder << id } - end - end - - return enumerator unless block_given? - - enumerator.each(&block) - - nil - end - # Deletes a message by ID. # @param id [Integer] the ID of the message to delete. # @return [Hash] details of the deleted message.