Skip to content

Instantly share code, notes, and snippets.

@chadwilken
Created June 23, 2022 14:56
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chadwilken/78097f8fd5dc760a67a060be81a313d6 to your computer and use it in GitHub Desktop.
Save chadwilken/78097f8fd5dc760a67a060be81a313d6 to your computer and use it in GitHub Desktop.
Searchkick Async Workflow
module Searchkick
class AsyncReindexStatus
include Redis::Objects
def id
'searchkick-async-reindex-status'
end
list :currently_reindexing
end
end
class AsyncReindexesController < BaseController
def index
@index_names = Searchkick::AsyncReindexStatus.new.currently_reindexing.to_a
end
def new
# In development it reloads each time and this list duplicates
@models = Searchkick.models.uniq(&:name).sort_by(&:name)
end
def create
Searchkick::PerformAsyncReindexWorker.perform_async(secure_params[:model])
redirect_to async_reindexes_path, notice: 'Enqueued reindexing operation, it will take a minute to show up here'
end
def show
@status = Searchkick.reindex_status(params[:id])
end
private
def secure_params
params.permit(:model)
end
end
<h1 class="page-title">Searchkick</h1>
<div class="listing">
<%= link_to 'New Async Reindex', new_async_reindex_path %>
<table>
<thead>
<tr>
<th>Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% @index_names.each do |index_name| %>
<tr>
<th><%= index_name %></th>
<th>
<%= link_to 'Status', async_reindex_path(id: index_name) %>
</th>
</tr>
<% end %>
</tbody>
</table>
</div>
module Searchkick
class MonitorAsyncReindexWorker
include Sidekiq::Worker
sidekiq_options retry: 0
def perform(klass, index_name)
status = Searchkick.reindex_status(index_name)
if status[:completed]
klass.constantize.search_index.promote(index_name)
Searchkick::AsyncReindexStatus.new.currently_reindexing.delete(index_name)
else
self.class.perform_in(10.seconds, klass, index_name)
end
end
end
end
<%= form_with(url: async_reindexes_path, method: :post, local: true) do |form| %>
<%= form.collection_select :model, @models, :name, :name %>
<%= form.submit 'Start Reindex', data: { confirm: 'Make sure you only run reindexing once per model' } %>
<% end %>
module Searchkick
class PerformAsyncReindexWorker
include Sidekiq::Worker
sidekiq_options retry: 0
def perform(klass)
result = klass.constantize.reindex(async: true)
index_name = result[:index_name]
Searchkick::AsyncReindexStatus.new.currently_reindexing << index_name
Searchkick::MonitorAsyncReindexWorker.perform_in(5.seconds, klass, index_name)
end
end
end
<h2><%= params[:id] %></h2>
<div class="single-page-section" id="details">
<div class="section-header">Details</div>
<p><span class="meta-label">Complete:</span> <%= @status[:completed] %></p>
<p><span class="meta-label">Batches Left:</span> <%= @status[:batches_left] %></p>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment