Skip to content
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
38 changes: 0 additions & 38 deletions lib/outboxer/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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<Integer>] 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.
Expand Down Expand Up @@ -682,13 +651,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.
Expand Down
97 changes: 0 additions & 97 deletions lib/outboxer/web.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
93 changes: 53 additions & 40 deletions lib/outboxer/web/views/messages.erb
Original file line number Diff line number Diff line change
Expand Up @@ -11,51 +11,64 @@
</div>
<!-- Buttons aligned to right on larger screens, hidden on smallest screens -->
<div class="col d-none d-sm-flex justify-content-end">
<form id="requeueAllForm" action="<%= outboxer_path("/messages/requeue_all") %>"
method="post" class="me-2">
<input type="hidden" name="action" value="requeue_all">
<% normalised_query_params.each do |key, param| %>
<input type="hidden" name="<%= key %>" value="<%= param %>">
<% end %>
<button type="submit" class="btn btn-sm btn-outline-secondary"
<%= 'disabled' unless Outboxer::Message
.can_requeue?(status: denormalised_query_params[:status]) %>>
<i class="bi bi-arrow-clockwise"></i> Requeue All
</button>
</form>
<form id="deleteAllForm" action="<%= outboxer_path("/messages/delete_all") %>" method="post">
<input type="hidden" name="action" value="delete_all">
<% normalised_query_params.each do |key, param| %>
<input type="hidden" name="<%= key %>" value="<%= param %>">
<% end %>
<button type="submit" class="btn btn-sm btn-outline-danger">
<i class="bi bi-trash"></i> Delete All
</button>
</form>
<!-- Requeue Page -->
<form action="<%= outboxer_path("/messages/update") %>" method="post" class="me-2">
<% normalised_query_params.each do |key, param| %>
<input type="hidden" name="<%= key %>" value="<%= param %>">
<% end %>
<input type="hidden" name="action" value="requeue_by_ids">
<% messages.each do |message| %>
<input type="hidden" name="selected_ids[]" value="<%= message[:id] %>">
<% end %>
<button type="submit" class="btn btn-sm btn-outline-secondary"
<%= 'disabled' unless Outboxer::Message.can_requeue?(status: denormalised_query_params[:status]) %>>
<i class="bi bi-arrow-clockwise"></i> Requeue Page
</button>
</form>

<!-- Delete Page -->
<form action="<%= outboxer_path("/messages/update") %>" method="post">
<% normalised_query_params.each do |key, param| %>
<input type="hidden" name="<%= key %>" value="<%= param %>">
<% end %>
<input type="hidden" name="action" value="delete_by_ids">
<% messages.each do |message| %>
<input type="hidden" name="selected_ids[]" value="<%= message[:id] %>">
<% end %>
<button type="submit" class="btn btn-sm btn-outline-danger">
<i class="bi bi-trash"></i> Delete Page
</button>
</form>
</div>
<!-- Buttons aligned underneath the header on the smallest screens -->
<div class="col-12 d-sm-none mt-2">
<% if Outboxer::Message.can_requeue?(status: denormalised_query_params[:status]) %>
<form id="requeueAllForm" action="<%= outboxer_path("/messages/requeue_all") %>" method="post" class="mb-2">
<input type="hidden" name="action" value="requeue_all">
<% normalised_query_params.each do |key, param| %>
<input type="hidden" name="<%= key %>" value="<%= param %>">
<% end %>

<button type="submit" class="btn btn-sm btn-outline-secondary w-100">
<i class="bi bi-arrow-clockwise"></i> Requeue All
</button>
</form>
<% if Outboxer::Message.can_requeue?(status: denormalised_query_params[:status]) %>
<form action="<%= outboxer_path("/messages/update") %>" method="post" class="mb-2">
<% normalised_query_params.each do |key, param| %>
<input type="hidden" name="<%= key %>" value="<%= param %>">
<% end %>
<form id="deleteAllForm" action="<%= outboxer_path("/messages/delete_all") %>" method="post">
<input type="hidden" name="action" value="delete_all">
<% normalised_query_params.each do |key, param| %>
<input type="hidden" name="<%= key %>" value="<%= param %>">
<% end %>
<button type="submit" class="btn btn-sm btn-outline-danger w-100">
<i class="bi bi-trash"></i> Delete All
</button>
<input type="hidden" name="action" value="requeue_by_ids">
<% messages.each do |message| %>
<input type="hidden" name="selected_ids[]" value="<%= message[:id] %>">
<% end %>
<button type="submit" class="btn btn-sm btn-outline-secondary w-100">
<i class="bi bi-arrow-clockwise"></i> Requeue Page
</button>
</form>
<% end %>

<form action="<%= outboxer_path("/messages/update") %>" method="post">
<% normalised_query_params.each do |key, param| %>
<input type="hidden" name="<%= key %>" value="<%= param %>">
<% end %>
<input type="hidden" name="action" value="delete_by_ids">
<% messages.each do |message| %>
<input type="hidden" name="selected_ids[]" value="<%= message[:id] %>">
<% end %>
<button type="submit" class="btn btn-sm btn-outline-danger w-100">
<i class="bi bi-trash"></i> Delete Page
</button>
</form>
</div>
</div>
</div>
Expand Down
39 changes: 0 additions & 39 deletions spec/lib/outboxer/message/can_requeue_all_spec.rb

This file was deleted.

94 changes: 0 additions & 94 deletions spec/lib/outboxer/web/messages/delete_all_spec.rb

This file was deleted.

Loading