Skip to content

Commit

Permalink
introduce explicit columns for tracking the status of ActiveJob
Browse files Browse the repository at this point in the history
  • Loading branch information
epugh committed Nov 1, 2024
1 parent 04c3b49 commit 396c0a6
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 45 deletions.
27 changes: 14 additions & 13 deletions app/controllers/api/v1/export/books_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,12 @@ def show
# api/v1/export/books_controller.rb ARE DUPLICATED
message = nil

# Use ActiveJob native (right now only in tests)
this_job_args = [ { _aj_globalid: @book.to_global_id.to_s } ]

job_queued_with_args = SolidQueue::Job.where(class_name: 'ExportBookJob', finished_at: nil).any? do |job|
job_args = job.arguments.to_h
SolidQueue::Job == this_job_args.all? { |hash| job_args.include?(hash) }
end

puts "job_queued_with_args: #{job_queued_with_args}"

if job_queued_with_args
message = 'Currently exporting book as file.'
if @book.export_job
message = "Currently exporting book as file. Status is #{@book.export_job}."
else
ExportBookJob.perform_later @book
track_book_export_queued do
ExportBookJob.perform_later(@book)
end
message = 'Starting export of book as file.'
end

Expand All @@ -40,6 +32,15 @@ def show
end
end
# rubocop:enable Metrics/MethodLength

private

def track_book_export_queued
@book.update(export_job: "queued at #{Time.zone.now}")

# Yield to the block to perform the job
yield if block_given?
end
end
end
end
Expand Down
26 changes: 14 additions & 12 deletions app/controllers/books/export_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,26 @@ def show
# api/v1/export/books_controller.rb ARE DUPLICATED
message = nil

this_job_args = [ { _aj_globalid: @book.to_global_id.to_s } ]

job_queued_with_args = SolidQueue::Job.where(class_name: 'ExportBookJob', finished_at: nil).any? do |job|
job_args = job.arguments.to_h
SolidQueue::Job == this_job_args.all? { |hash| job_args.include?(hash) }
end

puts "job_queued_with_args: #{job_queued_with_args}"

if job_queued_with_args
message = 'Currently exporting book as file.'
if @book.export_job
message = "Currently exporting book as file. Status is #{@book.export_job}."
else
@book.export_file.purge
ExportBookJob.perform_later @book
track_book_export_queued do
ExportBookJob.perform_later(@book)
end
message = 'Queued up export of book as file.'
end

redirect_to @book, notice: message
end

private

def track_book_export_queued
@book.update(export_job: "queued at #{Time.zone.now}")

# Yield to the block to perform the job
yield if block_given?
end
end
end
2 changes: 2 additions & 0 deletions app/jobs/export_book_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class ExportBookJob < ApplicationJob

# rubocop:disable Metrics/MethodLength
def perform book
book.update(export_job: "export started at #{Time.zone.now}")
Turbo::StreamsChannel.broadcast_render_to(
:notifications,
target: 'notifications',
Expand All @@ -29,6 +30,7 @@ def perform book

book.export_file.attach(io: compressed_data, filename: "book_export_#{book.id}.json.zip",
content_type: 'application/zip')
book.update(export_job: nil)

Turbo::StreamsChannel.broadcast_render_to(
:notifications,
Expand Down
3 changes: 3 additions & 0 deletions app/models/book.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
# Table name: books
#
# id :bigint not null, primary key
# export_job :string(255)
# import_job :string(255)
# name :string(255)
# populate_job :string(255)
# show_rank :boolean default(FALSE)
# support_implicit_judgements :boolean
# created_at :datetime not null
Expand Down
45 changes: 31 additions & 14 deletions app/views/books/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -93,20 +93,37 @@ This book consists of <%= @book.query_doc_pairs.count %> query document pairs an
<%= button_to 'Back to Books', books_path, method: :get %>
</p>

<h3>Export Data</h3>
<p>
Export just the <%= link_to 'judgement data', api_book_path(@book, format: :csv) %> in CSV format.
</p>
<p>
<%= link_to 'Export', books_export_path(@book), data: { turbo: false } %> the entire book in JSON format.
<% if @book.export_file.present? %>
There is an export file created <%= time_ago_in_words @book.export_file.created_at %> ago <%=link_to 'available here', rails_blob_path(@book.export_file.blob, only_path: true) %>.
<% end %>
</p>
<p>
To reference these judgements from a notebook or another system you can reference these <%= link_to 'Quepid APIs', apipie_apipie_path %> endpoints:
<code><%= api_book_path(@book, format: :csv) %></code> or <code><%= api_export_book_path(@book) %></code>
</p>
<div class="card" style="">
<div class="card-body">
<h5 class="card-title">Export Data</h5>
<p class="card-text">There are a number of ways to export the Book data.</p>

<ul class="list-group list-group-flush">
<li class="list-group-item">Export just the <%= link_to 'judgement data', api_book_path(@book, format: :csv) %> in CSV format. This will take a bit but you get a CSV file in your browser.</li>

<li class="list-group-item">Export the entire Book in JSON format.
<% if @book.export_job %>
The book is currently being exported. The status is <code><%=@book.export_job%></code>.
<% else %>
<%= button_to 'Export', books_export_path(@book), data: { turbo: false }, method: :get, class: "#{@book.export_job.nil? ? '' : 'disabled'}" %>
<% end %>
<% if @book.export_file.present? %>
<p>
There is an export file created <%= time_ago_in_words @book.export_file.created_at %> ago <%=link_to 'available here', rails_blob_path(@book.export_file.blob, only_path: true) %>.
</p>
<% end %>
</li>
<li class="list-group-item">
<p>
Reference these judgements from a notebook or another system you can use these <%= link_to 'Quepid APIs', apipie_apipie_path %> endpoints:
<code><%= api_book_path(@book, format: :csv) %></code> or <code><%= api_export_book_path(@book) %></code>
</p>

</li>
</ul>
</div>
</div>


<h3>Leaderboard</h3>
<div class="card">
Expand Down
7 changes: 7 additions & 0 deletions db/migrate/20241030230542_add_job_status_to_books.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class AddJobStatusToBooks < ActiveRecord::Migration[7.2]
def change
add_column :books, :export_job, :string
add_column :books, :import_job, :string
add_column :books, :populate_job, :string
end
end
5 changes: 4 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/controllers/api/v1/bulk/queries_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class QueriesControllerTest < ActionController::TestCase
post :create, params: data
end

assert result.real < 3, "Expecting less than 3 seconds. Elapsed time: #{result.real} seconds\n"
assert result.real < 5, "Expecting less than 5 seconds. Elapsed time: #{result.real} seconds\n"
# puts "Elapsed time: #{result.real} seconds\n"

acase.reload
Expand Down
11 changes: 7 additions & 4 deletions test/controllers/api/v1/export/books_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,21 @@ class BooksControllerTest < ActionController::TestCase
get :show, params: { book_id: book.id }
assert_response :ok

assert_enqueued_with(job: ExportBookJob, args: [ book ])
book.reload
assert book.export_job.starts_with? 'queued at'
# assert book.job_statuses

# duplicate call
get :show, params: { book_id: book.id }
assert_response :ok
body = response.parsed_body

assert_equal body['message'], 'Currently exporting book as file.'
assert body['message'].start_with? 'Currently exporting book as file. Status is queued at'

get :show, params: { book_id: book.id }
assert_response :ok
body = response.parsed_body

assert_equal body['message'], 'Currently exporting book as file.'
assert body['message'].start_with? 'Currently exporting book as file. Status is queued at'
end

test 'running a job and waiting gives you the resulting zip file' do
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/books.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
# Table name: books
#
# id :bigint not null, primary key
# export_job :string(255)
# import_job :string(255)
# name :string(255)
# populate_job :string(255)
# show_rank :boolean default(FALSE)
# support_implicit_judgements :boolean
# created_at :datetime not null
Expand Down
3 changes: 3 additions & 0 deletions test/jobs/export_book_job_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ class ExportBookJobTest < ActiveJob::TestCase
let(:book) { books(:james_bond_movies) }

test 'export the book works' do
assert_nil book.export_job
assert_not book.export_file.attached?

perform_enqueued_jobs do
ExportBookJob.perform_now(book)
# assert_not_nil book.export_job
end

assert_nil book.export_job
assert book.export_file.attached?

# Get the Active Storage attachment
Expand Down
3 changes: 3 additions & 0 deletions test/models/book_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
# Table name: books
#
# id :bigint not null, primary key
# export_job :string(255)
# import_job :string(255)
# name :string(255)
# populate_job :string(255)
# show_rank :boolean default(FALSE)
# support_implicit_judgements :boolean
# created_at :datetime not null
Expand Down

0 comments on commit 396c0a6

Please sign in to comment.