From 50020dd6efbee88e613172aa44d7a11a76c7d0ee Mon Sep 17 00:00:00 2001 From: Jie Chen Date: Fri, 12 Jun 2026 09:48:17 -0500 Subject: [PATCH 1/7] install rspec and init --- .rspec | 1 + Gemfile | 1 + Gemfile.lock | 25 ++++++++++++ bin/rspec | 16 ++++++++ spec/spec_helper.rb | 98 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 141 insertions(+) create mode 100644 .rspec create mode 100755 bin/rspec create mode 100644 spec/spec_helper.rb diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..c99d2e7 --- /dev/null +++ b/.rspec @@ -0,0 +1 @@ +--require spec_helper diff --git a/Gemfile b/Gemfile index 2cfe95f..e4c19e7 100644 --- a/Gemfile +++ b/Gemfile @@ -70,6 +70,7 @@ gem "arclight" group :development, :test do gem "solr_wrapper", ">= 0.3" + gem 'rspec-rails', '~> 8.0' end gem "rsolr", ">= 1.0", "< 3" gem "bootstrap", "~> 5.3" diff --git a/Gemfile.lock b/Gemfile.lock index 634e8f2..95f4995 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -139,6 +139,7 @@ GEM warden (~> 1.2.3) devise-guests (0.8.3) devise + diff-lcs (1.6.2) domain_name (0.6.20240107) dot-properties (0.1.4) bundler (>= 2.2.33) @@ -368,6 +369,23 @@ GEM rsolr (2.6.0) builder (>= 2.1.2) faraday (>= 0.9, < 3, != 2.0.0) + rspec-core (3.13.6) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.8) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-rails (8.0.4) + actionpack (>= 7.2) + activesupport (>= 7.2) + railties (>= 7.2) + rspec-core (>= 3.13.0, < 5.0.0) + rspec-expectations (>= 3.13.0, < 5.0.0) + rspec-mocks (>= 3.13.0, < 5.0.0) + rspec-support (>= 3.13.0, < 5.0.0) + rspec-support (3.13.7) rubocop (1.87.0) json (~> 2.3) language_server-protocol (~> 3.17.0.2) @@ -533,6 +551,7 @@ DEPENDENCIES puma (>= 5.0) rails (~> 8.1.3) rsolr (>= 1.0, < 3) + rspec-rails (~> 8.0) rubocop-rails-omakase selenium-webdriver solid_cable @@ -586,6 +605,7 @@ CHECKSUMS deprecation (1.1.0) sha256=01707cea9a6ed2d7270377457941f43394a345e6dd8048e1be6d18ff2f2a01e1 devise (5.0.4) sha256=d605f2b85854e74e56ee789e2d398702bc2d06e6bcd894717a670a3199c74cc1 devise-guests (0.8.3) sha256=3df086c2adad4ad66661020483c16de142a487eddf2672834a7345269b7f9fa4 + diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 domain_name (0.6.20240107) sha256=5f693b2215708476517479bf2b3802e49068ad82167bcd2286f899536a17d933 dot-properties (0.1.4) sha256=c41f5681d53e946ed5a2afa45bfd2dc8a4475980f62eba069ca83aaba2637004 dotenv (3.2.0) sha256=e375b83121ea7ca4ce20f214740076129ab8514cd81378161f11c03853fe619d @@ -689,6 +709,11 @@ CHECKSUMS retriable (4.1.1) sha256=6c25151721cba9d5d1c0aa9dbb38012aee36dd84752069f13dec98e7f8b51cec rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 rsolr (2.6.0) sha256=4b3bcea772cac300562775c20eeddedf63a6b7516a070cb6fbde000b09cfe12b + rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d + rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836 + rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47 + rspec-rails (8.0.4) sha256=06235692fc0892683d3d34977e081db867434b3a24ae0dd0c6f3516bad4e22df + rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c rubocop (1.87.0) sha256=b9d9ddf55116a513f8ef2c7ae660662d8b49301f118d3f0df61865b33a5c188d rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035 rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834 diff --git a/bin/rspec b/bin/rspec new file mode 100755 index 0000000..93e191c --- /dev/null +++ b/bin/rspec @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'rspec' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rspec-core", "rspec") diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..c80d44b --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,98 @@ +# This file was generated by the `rspec --init` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + + # This option will default to `:apply_to_host_groups` in RSpec 4 (and will + # have no way to turn it off -- the option exists only for backwards + # compatibility in RSpec 3). It causes shared context metadata to be + # inherited by the metadata hash of host groups and examples, rather than + # triggering implicit auto-inclusion in groups with matching metadata. + config.shared_context_metadata_behavior = :apply_to_host_groups + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # This allows you to limit a spec run to individual examples or groups + # you care about by tagging them with `:focus` metadata. When nothing + # is tagged with `:focus`, all examples get run. RSpec also provides + # aliases for `it`, `describe`, and `context` that include `:focus` + # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + config.filter_run_when_matching :focus + + # Allows RSpec to persist some state between runs in order to support + # the `--only-failures` and `--next-failure` CLI options. We recommend + # you configure your source control system to ignore this file. + config.example_status_persistence_file_path = "spec/examples.txt" + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/ + config.disable_monkey_patching! + + # This setting enables warnings. It's recommended, but in some cases may + # be too noisy due to issues in dependencies. + config.warnings = true + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = "doc" + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end From 9e9207baa3bf17903b84c1661f4eb17c3078f538 Mon Sep 17 00:00:00 2001 From: Jie Chen Date: Fri, 12 Jun 2026 10:06:54 -0500 Subject: [PATCH 2/7] add rspec helper and test for user model --- spec/models/user_spec.rb | 82 ++++++++++++++++++++++++++++++++++++++++ spec/rails_helper.rb | 72 +++++++++++++++++++++++++++++++++++ spec/spec_helper.rb | 6 +-- 3 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 spec/models/user_spec.rb create mode 100644 spec/rails_helper.rb diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb new file mode 100644 index 0000000..8028f7c --- /dev/null +++ b/spec/models/user_spec.rb @@ -0,0 +1,82 @@ +require 'rails_helper' + +RSpec.describe User, type: :model do + subject(:user) { described_class.new(email: 'user@example.com', password: 'password123') } + + describe 'validations' do + it 'is valid with an email and password' do + expect(user).to be_valid + end + + it 'requires an email' do + user.email = '' + expect(user).not_to be_valid + expect(user.errors[:email]).to include("can't be blank") + end + + it 'requires a valid email format' do + user.email = 'not-an-email' + expect(user).not_to be_valid + expect(user.errors[:email]).to be_present + end + + it 'requires the email to be unique (case-insensitively)' do + described_class.create!(email: 'user@example.com', password: 'password123') + duplicate = described_class.new(email: 'USER@example.com', password: 'password123') + expect(duplicate).not_to be_valid + expect(duplicate.errors[:email]).to include('has already been taken') + end + + it 'requires a password' do + user.password = nil + expect(user).not_to be_valid + expect(user.errors[:password]).to include("can't be blank") + end + + it 'requires the password and its confirmation to match' do + user.password_confirmation = 'mismatch' + expect(user).not_to be_valid + expect(user.errors[:password_confirmation]).to be_present + end + end + + describe 'devise modules' do + it 'enables the expected devise modules' do + expect(described_class.devise_modules).to include( + :database_authenticatable, + :registerable, + :recoverable, + :rememberable, + :validatable + ) + end + + it 'authenticates with the correct password' do + user.save! + expect(user.valid_password?('password123')).to be(true) + expect(user.valid_password?('wrong')).to be(false) + end + + it 'encrypts the password rather than storing it in plain text' do + user.save! + expect(user.encrypted_password).to be_present + expect(user.encrypted_password).not_to eq('password123') + end + end + + describe 'attributes' do + it 'defaults guest to false' do + expect(described_class.new.guest).to be(false) + end + end + + describe 'Blacklight integration' do + it 'exposes email as the displayable login key' do + expect(described_class.string_display_key).to eq(:email) + end + + it 'includes Blacklight::User' do + expect(described_class.ancestors).to include(Blacklight::User) + end + end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb new file mode 100644 index 0000000..ef75d46 --- /dev/null +++ b/spec/rails_helper.rb @@ -0,0 +1,72 @@ +# This file is copied to spec/ when you run 'rails generate rspec:install' +require 'spec_helper' +ENV['RAILS_ENV'] ||= 'test' +require_relative '../config/environment' +# Prevent database truncation if the environment is production +abort("The Rails environment is running in production mode!") if Rails.env.production? +# Uncomment the line below in case you have `--require rails_helper` in the `.rspec` file +# that will avoid rails generators crashing because migrations haven't been run yet +# return unless Rails.env.test? +require 'rspec/rails' +# Add additional requires below this line. Rails is not loaded until this point! + +# Requires supporting ruby files with custom matchers and macros, etc, in +# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are +# run as spec files by default. This means that files in spec/support that end +# in _spec.rb will both be required and run as specs, causing the specs to be +# run twice. It is recommended that you do not name files matching this glob to +# end with _spec.rb. You can configure this pattern with the --pattern +# option on the command line or in ~/.rspec, .rspec or `.rspec-local`. +# +# The following line is provided for convenience purposes. It has the downside +# of increasing the boot-up time by auto-requiring all files in the support +# directory. Alternatively, in the individual `*_spec.rb` files, manually +# require only the support files necessary. +# +# Rails.root.glob('spec/support/**/*.rb').sort_by(&:to_s).each { |f| require f } + +# Ensures that the test database schema matches the current schema file. +# If there are pending migrations it will invoke `db:test:prepare` to +# recreate the test database by loading the schema. +# If you are not using ActiveRecord, you can remove these lines. +begin + ActiveRecord::Migration.maintain_test_schema! +rescue ActiveRecord::PendingMigrationError => e + abort e.to_s.strip +end +RSpec.configure do |config| + # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures + config.fixture_paths = [ + Rails.root.join('spec/fixtures') + ] + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, remove the following line or assign false + # instead of true. + config.use_transactional_fixtures = true + + # You can uncomment this line to turn off ActiveRecord support entirely. + # config.use_active_record = false + + # RSpec Rails uses metadata to mix in different behaviours to your tests, + # for example enabling you to call `get` and `post` in request specs. e.g.: + # + # RSpec.describe UsersController, type: :request do + # # ... + # end + # + # The different available types are documented in the features, such as in + # https://rspec.info/features/8-0/rspec-rails + # + # You can also infer these behaviours automatically by location, e.g. + # /spec/models would pull in the same behaviour as `type: :model` but this + # behaviour is considered legacy and will be removed in a future version. + # + # To enable this behaviour uncomment the line below. + # config.infer_spec_type_from_file_location! + + # Filter lines from Rails gems in backtraces. + config.filter_rails_from_backtrace! + # arbitrary gems may also be filtered via: + # config.filter_gems_from_backtrace("gem name") +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c80d44b..327b58e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,4 @@ -# This file was generated by the `rspec --init` command. Conventionally, all +# This file was generated by the `rails generate rspec:install` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # The generated `.rspec` file contains `--require spec_helper` which will cause # this file to always be loaded, without a need to explicitly require it in any @@ -64,10 +64,6 @@ # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/ config.disable_monkey_patching! - # This setting enables warnings. It's recommended, but in some cases may - # be too noisy due to issues in dependencies. - config.warnings = true - # Many RSpec users commonly either run the entire suite or an individual # file, and it's useful to allow more verbose output when running an # individual spec file. From fcafcf4d5f8b28b65f2157370686c23926261b7a Mon Sep 17 00:00:00 2001 From: Jie Chen Date: Fri, 12 Jun 2026 10:28:55 -0500 Subject: [PATCH 3/7] install resque and saved Claude recommendation --- Gemfile | 6 +++ Gemfile.lock | 114 ++++++++++++++++++++++++++++++++++++++++++++ resque.md | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 resque.md diff --git a/Gemfile b/Gemfile index e4c19e7..acf9221 100644 --- a/Gemfile +++ b/Gemfile @@ -42,6 +42,12 @@ gem "thruster", require: false # Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] gem "image_processing", "~> 2.0" +# job worker queue +gem "resque", "~> 2.6" +gem "redis" +gem "resque-scheduler" +gem "resque-web" + group :development, :test do # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem gem "debug", platforms: %i[ mri windows ], require: "debug/prelude" diff --git a/Gemfile.lock b/Gemfile.lock index 95f4995..f03008d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -119,6 +119,14 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) + coffee-rails (5.0.0) + coffee-script (>= 2.2.0) + railties (>= 5.2.0) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.12.2) + commonjs (0.2.7) concurrent-ruby (1.3.6) connection_pool (3.0.2) crass (1.0.6) @@ -150,6 +158,7 @@ GEM erubi (1.13.1) et-orbi (1.4.0) tzinfo + execjs (2.10.1) faraday (2.14.2) faraday-net_http (>= 2.0, < 3.5) json @@ -168,6 +177,8 @@ GEM ffi-compiler (1.4.2) ffi (>= 1.15.5) rake + font-awesome-sass (6.7.2) + sassc (~> 2.0) fugit (1.12.2) et-orbi (~> 1.4) raabro (~> 1.4) @@ -204,6 +215,10 @@ GEM jbuilder (2.15.1) actionview (>= 7.0.0) activesupport (>= 7.0.0) + jquery-rails (4.6.1) + rails-dom-testing (>= 1, < 3) + railties (>= 4.2.0) + thor (>= 0.14, < 2.0) json (2.19.8) jsonpath (1.1.5) multi_json @@ -231,6 +246,12 @@ GEM kaminari-core (= 1.2.2) kaminari-core (1.2.2) language_server-protocol (3.17.0.5) + less (2.6.0) + commonjs (~> 0.2.7) + less-rails (4.0.0) + actionpack (>= 4) + less (~> 2.6.0) + sprockets (>= 2) lint_roller (1.1.0) llhttp-ffi (0.5.1) ffi-compiler (~> 1.0) @@ -257,8 +278,10 @@ GEM minitest (6.0.6) drb (~> 2.0) prism (~> 1.5) + mono_logger (1.1.2) msgpack (1.8.1) multi_json (1.21.1) + mustermann (3.1.1) mutex_m (0.3.0) net-http (0.9.1) uri (>= 0.11.1) @@ -315,6 +338,10 @@ GEM raabro (1.4.0) racc (1.8.1) rack (3.2.6) + rack-protection (4.2.1) + base64 (>= 0.1.0) + logger (>= 1.6.0) + rack (>= 3.0.0, < 4) rack-session (2.1.2) base64 (>= 0.1.0) rack (>= 3.0.0) @@ -358,12 +385,35 @@ GEM erb psych (>= 4.0.0) tsort + redis (5.4.1) + redis-client (>= 0.22.0) + redis-client (0.30.0) + connection_pool + redis-namespace (1.11.0) + redis (>= 4) regexp_parser (2.12.0) reline (0.6.3) io-console (~> 0.5) responders (3.2.0) actionpack (>= 7.0) railties (>= 7.0) + resque (2.7.0) + mono_logger (~> 1) + multi_json (~> 1.0) + redis-namespace (~> 1.6) + sinatra (>= 0.9.2) + resque-scheduler (4.11.0) + mono_logger (~> 1.0) + redis (>= 3.3) + resque (>= 1.27) + rufus-scheduler (~> 3.2, != 3.3) + resque-web (0.0.12) + coffee-rails + font-awesome-sass + jquery-rails + resque + sass-rails + twitter-bootstrap-rails retriable (4.1.1) rexml (3.4.4) rsolr (2.6.0) @@ -416,6 +466,18 @@ GEM rubocop-rails (>= 2.30) ruby-progressbar (1.13.0) rubyzip (3.3.1) + rufus-scheduler (3.9.2) + fugit (~> 1.1, >= 1.11.1) + sass-rails (6.0.0) + sassc-rails (~> 2.1, >= 2.1.1) + sassc (2.4.0) + ffi (~> 1.9) + sassc-rails (2.1.2) + railties (>= 4.0.0) + sassc (>= 2.0) + sprockets (> 3.0) + sprockets-rails + tilt securerandom (0.4.1) selenium-webdriver (4.44.0) base64 (~> 0.2) @@ -423,6 +485,13 @@ GEM rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 4.0) websocket (~> 1.0) + sinatra (4.2.1) + logger (>= 1.6.0) + mustermann (~> 3.0) + rack (>= 3.0.0, < 4) + rack-protection (= 4.2.1) + rack-session (>= 2.0.0, < 3) + tilt (~> 2.0) slop (4.10.1) solid_cable (4.0.0) actioncable (>= 7.2) @@ -447,6 +516,14 @@ GEM ostruct retriable ruby-progressbar + sprockets (4.2.2) + concurrent-ruby (~> 1.0) + logger + rack (>= 2.2.4, < 4) + sprockets-rails (3.5.2) + actionpack (>= 6.1) + activesupport (>= 6.1) + sprockets (>= 3.0.0) sqlite3 (2.9.5-aarch64-linux-gnu) sqlite3 (2.9.5-aarch64-linux-musl) sqlite3 (2.9.5-arm-linux-gnu) @@ -469,6 +546,7 @@ GEM thruster (0.1.21-aarch64-linux) thruster (0.1.21-arm64-darwin) thruster (0.1.21-x86_64-linux) + tilt (2.7.0) timeout (0.6.1) traject (3.8.3) concurrent-ruby (>= 0.8.0) @@ -493,6 +571,11 @@ GEM turbo-rails (2.0.23) actionpack (>= 7.1.0) railties (>= 7.1.0) + twitter-bootstrap-rails (5.3.0) + actionpack (>= 5.0, < 9.0) + execjs (~> 2.7) + less-rails (~> 4.0) + railties (>= 5.0, < 9.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (3.2.0) @@ -550,6 +633,10 @@ DEPENDENCIES propshaft puma (>= 5.0) rails (~> 8.1.3) + redis + resque (~> 2.6) + resque-scheduler + resque-web rsolr (>= 1.0, < 3) rspec-rails (~> 8.0) rubocop-rails-omakase @@ -595,6 +682,10 @@ CHECKSUMS bundler (4.0.13) sha256=19f08be7f27022cf0b89f27da0b044ae075e8270a9ef44ad248a932614e1ca3b bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 capybara (3.40.0) sha256=42dba720578ea1ca65fd7a41d163dd368502c191804558f6e0f71b391054aeef + coffee-rails (5.0.0) sha256=5daaa1ba51fd4907c98a333b6a9e7c1a99b1fff57fcef999b6c62d813cb91a9c + coffee-script (2.4.1) sha256=82fe281e11b93c8117b98c5ea8063e71741870f1c4fbb27177d7d6333dd38765 + coffee-script-source (1.12.2) sha256=e12b16fd8927fbbf8b87cb2e9a85a6cf457c6881cc7ff8b1af15b31f70da07a4 + commonjs (0.2.7) sha256=66cf6883f51c17e2e21bce704574224633cdc7a89bd21ae4c9853bdbd3d76ab8 concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a crass (1.0.6) sha256=dc516022a56e7b3b156099abc81b6d2b08ea1ed12676ac7a5657617f012bd45d @@ -614,6 +705,7 @@ CHECKSUMS erb (6.0.4) sha256=38e3803694be357fe2bfe312487c74beaf9fb4e5beb3e22498952fe1645b95d9 erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9 et-orbi (1.4.0) sha256=6c7e3c90779821f9e3b324c5e96fda9767f72995d6ae435b96678a4f3e2de8bc + execjs (2.10.1) sha256=abe0ae028467eb8e30c10814eb934d07876a691aae7e803d813b7ce5a75e73f1 faraday (2.14.2) sha256=73ccb9994a9e8648f010e32eca2ae82e41c57860aa10932cda29418b9e0223ad faraday-follow_redirects (0.5.0) sha256=5cde93c894b30943a5d2b93c2fe9284216a6b756f7af406a1e55f211d97d10ad faraday-net_http (3.4.4) sha256=0e78af151747ed1b00f33e25973b4bc220d7f16c00c39676817c8b12331eb588 @@ -625,6 +717,7 @@ CHECKSUMS ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e ffi-compiler (1.4.2) sha256=a9d69d5d9ced6f64776ddafa535867ad90e5740ad37bed7afb4de6e450da126e + font-awesome-sass (6.7.2) sha256=31cf171c593cda4118bf5efbf9e4eb6abc8b15fd4d6acd5f000026356ee0005d fugit (1.12.2) sha256=643f2bf28db263bd400cbf8e0dd8b76b2c9b94bdb130e12d2394de04d9c20e5e globalid (1.3.0) sha256=05c639ad6eb4594522a0b07983022f04aa7254626ab69445a0e493aa3786ff11 gretel (5.1.0) sha256=7324d255dca34b8997cba2d207f29c11b9cdbd4e72bd5d6392cf67da46b9cdaf @@ -639,6 +732,7 @@ CHECKSUMS io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 jbuilder (2.15.1) sha256=2430bec28fb0cebacb5875b1009cf9d8bc3c303ccb810c4c8b062a4b51457637 + jquery-rails (4.6.1) sha256=619f3496cdcdeaae1fd6dafa52dbac3fc45b745d4e09712da4184a16b3a8d9c0 json (2.19.8) sha256=6354310fd76ef69b87d5bd1f38b40d730613baf90b6803d2d0a48f618d32dfaa jsonpath (1.1.5) sha256=29f70467193a2dc93ab864ec3d3326d54267961acc623f487340eb9c34931dbe kamal (2.11.0) sha256=1408864425e0dec7e0a14d712a3b13f614e9f3a425b7661d3f9d287a51d7dd75 @@ -647,6 +741,8 @@ CHECKSUMS kaminari-activerecord (1.2.2) sha256=0dd3a67bab356a356f36b3b7236bcb81cef313095365befe8e98057dd2472430 kaminari-core (1.2.2) sha256=3bd26fec7370645af40ca73b9426a448d09b8a8ba7afa9ba3c3e0d39cdbb83ff language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc + less (2.6.0) sha256=266038742de84e69fc62f78018ac8e776932054572bf4863477a209d27dc2e4e + less-rails (4.0.0) sha256=567a3a8e4061510fcbb1097afd29e863231def23002d82722e6ba1357d776a55 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 llhttp-ffi (0.5.1) sha256=9a25a7fc19311f691a78c9c0ac0fbf4675adbd0cca74310228fdf841018fa7bc logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 @@ -659,8 +755,10 @@ CHECKSUMS mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef minitar (1.1.0) sha256=38db0cfb6f3801017946cdcd8dc53f2cf3fd41ff752892312bf9a1639c9ea23e minitest (6.0.6) sha256=153ea36d1d987a62942382b61075745042a2b3123b1cd48f4c3675af9cc7d6f1 + mono_logger (1.1.2) sha256=2e359def7007f5c908aadd953687991fe667995d14ae5f0d10dda76e3e8670f7 msgpack (1.8.1) sha256=3fef787cd3965fd119c08a22724a56a93ca25008c3421fc15039f603a8b7c86c multi_json (1.21.1) sha256=e6126a31808e3b4d19f483c775ceac34df190dffa62adfb63a165ee14ba68080 + mustermann (3.1.1) sha256=4c6170c7234d5499c345562ba7c7dfe73e1754286dcc1abb053064d66a127198 mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996 net-imap (0.6.4) sha256=9a5598c67a3022c284d98430ef1d4948e7dbdb62596f61081ea8ca933270a02b @@ -693,6 +791,7 @@ CHECKSUMS raabro (1.4.0) sha256=d4fa9ff5172391edb92b242eed8be802d1934b1464061ae5e70d80962c5da882 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rack (3.2.6) sha256=5ed78e1f73b2e25679bec7d45ee2d4483cc4146eb1be0264fc4d94cb5ef212c2 + rack-protection (4.2.1) sha256=cf6e2842df8c55f5e4d1a4be015e603e19e9bc3a7178bae58949ccbb58558bac rack-session (2.1.2) sha256=595434f8c0c3473ae7d7ac56ecda6cc6dfd9d37c0b2b5255330aa1576967ffe8 rack-test (2.2.0) sha256=005a36692c306ac0b4a9350355ee080fd09ddef1148a5f8b2ac636c720f5c463 rackup (2.3.1) sha256=6c79c26753778e90983761d677a48937ee3192b3ffef6bc963c0950f94688868 @@ -703,9 +802,15 @@ CHECKSUMS rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701 rdoc (7.2.0) sha256=8650f76cd4009c3b54955eb5d7e3a075c60a57276766ebf36f9085e8c9f23192 + redis (5.4.1) sha256=b5e675b57ad22b15c9bcc765d5ac26f60b675408af916d31527af9bd5a81faae + redis-client (0.30.0) sha256=743f11ed42f0a41a0341554087b077479fec7e2d47a7c123fd90a12c0db5e477 + redis-namespace (1.11.0) sha256=e91a1aa2b2d888b6dea1d4ab8d39e1ae6fac3426161feb9d91dd5cca598a2239 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835 responders (3.2.0) sha256=89c2d6ac0ae16f6458a11524cae4a8efdceba1a3baea164d28ee9046bd3df55a + resque (2.7.0) sha256=685fdc8889b0a649183ff9b23c96817f42a1e1d47c0ea64c77c5e1dd69b961b0 + resque-scheduler (4.11.0) sha256=4e8bf3acdccc2cfe02141d2717fc03dc6e0cdd887c0d6c0fa92b394aa70f32a1 + resque-web (0.0.12) sha256=3a282638983c760927156f4ddd7273d4b07526579f8e81b03577950c57a4c472 retriable (4.1.1) sha256=6c25151721cba9d5d1c0aa9dbb38012aee36dd84752069f13dec98e7f8b51cec rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 rsolr (2.6.0) sha256=4b3bcea772cac300562775c20eeddedf63a6b7516a070cb6fbde000b09cfe12b @@ -721,13 +826,20 @@ CHECKSUMS rubocop-rails-omakase (1.1.0) sha256=2af73ac8ee5852de2919abbd2618af9c15c19b512c4cfc1f9a5d3b6ef009109d ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 rubyzip (3.3.1) sha256=2ed92112c7c43ba2b2527f35e6d99d9c2c99270b640aad5227516436481b1e4e + rufus-scheduler (3.9.2) sha256=55fa9e4db0ff69d7f38c804f17baba0c9bce5cba39984ae3c5cf6c039d1323b9 + sass-rails (6.0.0) sha256=e0b6448ea1c7929fd5929fc7a8eb2d78045e44cc82fc0765a249d3fa1c5810d3 + sassc (2.4.0) sha256=4c60a2b0a3b36685c83b80d5789401c2f678c1652e3288315a1551d811d9f83e + sassc-rails (2.1.2) sha256=5f4fdf3881fc9bdc8e856ffbd9850d70a2878866feae8114aa45996179952db5 securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 selenium-webdriver (4.44.0) sha256=6f1df072529af369589c46f0e01132952aabb250cfd683c274d74dc1eb5d8477 + sinatra (4.2.1) sha256=b7aeb9b11d046b552972ade834f1f9be98b185fa8444480688e3627625377080 slop (4.10.1) sha256=844322b5ffcf17ed4815fdb173b04a20dd82b4fd93e3744c88c8fafea696d9c7 solid_cable (4.0.0) sha256=8379680ef6bf36e195eb876a6306ea290f87d5fa10bc4a757bc2a918f83229b5 solid_cache (1.0.10) sha256=bc05a2fb3ac78a6f43cbb5946679cf9db67dd30d22939ededc385cb93e120d41 solid_queue (1.4.0) sha256=e6a18d196f0b27cb6e3c77c5b31258b05fb634f8ed64fb1866ed164047216c2a solr_wrapper (4.4.0) sha256=1eaf0667611a90c623d05c3c2c765d7a2e4174427d03580396cc2124b10430bb + sprockets (4.2.2) sha256=761e5a49f1c288704763f73139763564c845a8f856d52fba013458f8af1b59b1 + sprockets-rails (3.5.2) sha256=a9e88e6ce9f8c912d349aa5401509165ec42326baf9e942a85de4b76dbc4119e sqlite3 (2.9.5-aarch64-linux-gnu) sha256=78075b6337d3d182c6d2b4691049ed45cd220826160c9ea18946bf6a1de200dc sqlite3 (2.9.5-aarch64-linux-musl) sha256=18c801185deb4adc01ddb281e8f672a39e3d1729979ca91e39439cd3eac0402d sqlite3 (2.9.5-arm-linux-gnu) sha256=1bdfca0c7d63998c60b0f4a8e3c8df2d33800ccc4abd2d612eddbbbc92a4c48b @@ -743,11 +855,13 @@ CHECKSUMS thruster (0.1.21-aarch64-linux) sha256=f5aff78fb7a6431ed3d6ab4bde03a89c461e9a73981dbc97d6990d85c3db235c thruster (0.1.21-arm64-darwin) sha256=bd8db9f57fae2cbb3fe08ebab49cb47fe49608122dac23daf0ce709adfb9bfc8 thruster (0.1.21-x86_64-linux) sha256=6e2fbcf826540a72d3710ae4db072c2333287ac2ee57e7e52f35bc10900d74a7 + tilt (2.7.0) sha256=0d5b9ba69f6a36490c64b0eee9f6e9aad517e20dcc848800a06eb116f08c6ab3 timeout (0.6.1) sha256=78f57368a7e7bbadec56971f78a3f5ecbcfb59b7fcbb0a3ed6ddc08a5094accb traject (3.8.3) sha256=db615df38e28af4b9780bbba52b365ec38d211108eaa942d4f490d7134e13585 traject_plus (2.0.1) sha256=442e9e9ad4bbbfa22214a71e7d5ac80a99778de3805d539ee57b141846c19084 tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f turbo-rails (2.0.23) sha256=ee0d90733aafff056cf51ff11e803d65e43cae258cc55f6492020ec1f9f9315f + twitter-bootstrap-rails (5.3.0) sha256=21b15dde99bc0d8981162b03feb3c56ee35d7c22f534a1b351ec5a3ff0647d3e tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f diff --git a/resque.md b/resque.md new file mode 100644 index 0000000..f4c9e44 --- /dev/null +++ b/resque.md @@ -0,0 +1,131 @@ +# Resque on boxrunner — Recommendations + +## Context + +- **Rails:** 8.1.3 +- **Ruby:** 3.4.9 +- **Current Active Job adapter:** `:solid_queue` (see `config/environments/production.rb`) + +Because this is a Rails 8 app already wired up with Solid Queue, the recommendation +below leads with "should you?" before "how". + +## Should you use Resque on Rails 8? + +For a **new** Rails 8 app, Resque is usually *not* the best choice anymore: + +- **Solid Queue** (already your adapter) is the Rails 8 default. It's database-backed, + needs **no Redis**, and is maintained by the Rails team. You already have it wired up. +- **Sidekiq** is the most popular Redis-backed option — multithreaded, far more efficient + than Resque (which is process-per-worker), actively maintained, and the de-facto standard + if you *do* want Redis. +- **Resque** is mature and battle-tested but comparatively dated: it forks one process per + job (memory-heavy), and the ecosystem has largely moved to Sidekiq/Solid Queue. + +**Only reach for Resque if you have a specific reason** (existing Resque infrastructure, +team familiarity, a plugin you depend on). Otherwise stick with Solid Queue or pick Sidekiq. + +## Installing & configuring Resque (best practice) + +### 1. Gems + +```ruby +# Gemfile +gem "resque", "~> 2.6" +gem "redis" +# Optional but recommended: +gem "resque-scheduler" # cron-style + delayed jobs +gem "resque-web" # the dashboard (extracted from core in Resque 2.x) +``` + +```bash +bundle install +``` + +### 2. Use it *through* Active Job, not directly + +The single most important best practice: **don't write `Resque.enqueue` and +`def self.perform` everywhere.** Use Active Job with the Resque adapter so your job code +stays backend-agnostic. + +```ruby +# config/application.rb (or per-environment) +config.active_job.queue_adapter = :resque +``` + +```ruby +# app/jobs/welcome_email_job.rb +class WelcomeEmailJob < ApplicationJob + queue_as :default + + def perform(user_id) + user = User.find(user_id) + UserMailer.welcome(user).deliver_now + end +end + +WelcomeEmailJob.perform_later(user.id) +``` + +This way, if you later move to Sidekiq or Solid Queue, you change one config line, +not your jobs. + +### 3. Redis connection — make it environment-driven + +```ruby +# config/initializers/resque.rb +require "resque" + +Resque.redis = ENV.fetch("REDIS_URL", "redis://localhost:6379/0") +Resque.redis.namespace = "resque:boxrunner" +``` + +Drive `REDIS_URL` from Rails credentials / env vars; never hardcode production hosts. + +### 4. Workers — rake task + queue list + +Run workers in priority order: + +```bash +QUEUE=critical,default,low bundle exec rake resque:work +``` + +In production, supervise workers with **systemd**, **foreman/Procfile**, or your container +orchestrator — one process per worker, and run multiple processes for concurrency +(Resque is single-job-per-process). + +### 5. Restart workers on deploy + +Resque workers load your app code at boot and **don't pick up new code automatically**. +Your deploy must restart (or send `QUIT` for graceful shutdown of) workers, or you'll run +stale code. This is a common production gotcha. + +### 6. Dashboard — mount it securely behind auth + +```ruby +# config/routes.rb +require "resque/server" + +authenticate :user, ->(u) { u.admin? } do # requires an admin flag on User + mount Resque::Server.new, at: "/resque" +end +``` + +Never expose `/resque` unauthenticated — it can delete/retry jobs. + +### 7. Failure handling + +- Configure the failure backend (Redis by default) and monitor the failed queue. +- For automatic retries, add `gem "resque-retry"` (Resque core has none built in — unlike + Sidekiq/Active Job's `retry_on`). Note that Active Job's `retry_on`/`discard_on` *do* + work through the adapter, which is another reason to go via Active Job. + +### 8. Don't enqueue inside DB transactions + +Enqueue jobs **after_commit**, not inside a transaction — otherwise a worker may pick up +the job before the record is committed (or after a rollback) and fail with +"record not found." + +## Recommendation for this app + +**Stay on Solid Queue** unless you have a concrete reason to need Resque/Redis. If you do +need a Redis-backed queue, prefer **Sidekiq** over Resque for new work. From 480589312516cdc3ccbd80ce253217907d6cd4e5 Mon Sep 17 00:00:00 2001 From: Jie Chen Date: Fri, 12 Jun 2026 10:43:48 -0500 Subject: [PATCH 4/7] add redis service to docker compose file --- compose.yml | 17 +++++++++++++++++ config/initializers/resque.rb | 6 ++++++ 2 files changed, 23 insertions(+) create mode 100644 config/initializers/resque.rb diff --git a/compose.yml b/compose.yml index e2b12f4..dacfae7 100644 --- a/compose.yml +++ b/compose.yml @@ -4,14 +4,30 @@ services: depends_on: solr: condition: service_healthy + redis: + condition: service_healthy build: context: . ports: - '3000:3000' environment: - SOLR_URL=http://solr:8983/solr/blacklight-collection + - REDIS_URL=redis://redis:6379/0 env_file: - .env + redis: + image: redis:7 + healthcheck: + interval: 30s + timeout: 10s + start_period: 30s + retries: 5 + test: ["CMD", "redis-cli", "ping"] + ports: + - '6379:6379' + volumes: + - redis-data:/data + command: redis-server --appendonly yes solr: depends_on: zookeeper: @@ -48,3 +64,4 @@ services: ZOO_SERVERS: server.1=0.0.0.0:2888:3888;2181 volumes: solr-data: + redis-data: diff --git a/config/initializers/resque.rb b/config/initializers/resque.rb new file mode 100644 index 0000000..9cd0db2 --- /dev/null +++ b/config/initializers/resque.rb @@ -0,0 +1,6 @@ + +# config/initializers/resque.rb +require "resque" + +Resque.redis = ENV.fetch("REDIS_URL", "redis://localhost:6379/0") +Resque.redis.namespace = "resque:boxrunner" \ No newline at end of file From 9a557dec3df3cf47bce4ea1f92927384bc7acc5d Mon Sep 17 00:00:00 2001 From: Jie Chen Date: Fri, 12 Jun 2026 12:17:06 -0500 Subject: [PATCH 5/7] add resque and resque-web services to compose file --- compose.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/compose.yml b/compose.yml index dacfae7..f5d374d 100644 --- a/compose.yml +++ b/compose.yml @@ -28,6 +28,28 @@ services: volumes: - redis-data:/data command: redis-server --appendonly yes + resque: + depends_on: + redis: + condition: service_healthy + build: + context: . + environment: + - SOLR_URL=http://solr:8983/solr/blacklight-collection + - REDIS_URL=redis://redis:6379/0 + - QUEUE=* + env_file: + - .env + command: bundle exec rake environment resque:work + resque-web: + depends_on: + redis: + condition: service_healthy + build: + context: . + ports: + - '5678:5678' + command: bundle exec resque-web -F -L -p 5678 -r redis://redis:6379/0 -N resque:boxrunner solr: depends_on: zookeeper: From 0988a5b9e0228dd268dbb3cc43b1aef4d3fc6b20 Mon Sep 17 00:00:00 2001 From: Jie Chen Date: Fri, 12 Jun 2026 12:48:58 -0500 Subject: [PATCH 6/7] fix errors to get the docker compose up works and create the resque-web config --- app/assets/config/manifest.js | 2 ++ app/views/layouts/application.html.erb | 2 +- compose.yml | 5 ++++- config/environments/production.rb | 5 +++++ config/resque_web.ru | 14 ++++++++++++++ 5 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 app/assets/config/manifest.js create mode 100644 config/resque_web.ru diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js new file mode 100644 index 0000000..9a99757 --- /dev/null +++ b/app/assets/config/manifest.js @@ -0,0 +1,2 @@ +//= link_tree ../images +//= link_tree ../builds diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index f5f1c5e..c74a761 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -19,7 +19,7 @@ <%# Includes all stylesheet files in app/assets/stylesheets %> - <%= stylesheet_link_tag :app, "data-turbo-track": "reload" %> + <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> <%= javascript_importmap_tags %> diff --git a/compose.yml b/compose.yml index f5d374d..a90667a 100644 --- a/compose.yml +++ b/compose.yml @@ -47,9 +47,12 @@ services: condition: service_healthy build: context: . + environment: + - REDIS_URL=redis://redis:6379/0 + - RESQUE_NAMESPACE=resque:boxrunner ports: - '5678:5678' - command: bundle exec resque-web -F -L -p 5678 -r redis://redis:6379/0 -N resque:boxrunner + command: bundle exec rackup -o 0.0.0.0 -p 5678 config/resque_web.ru solr: depends_on: zookeeper: diff --git a/config/environments/production.rb b/config/environments/production.rb index f5763e0..789e8e9 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -18,6 +18,11 @@ # Cache assets for far-future expiry since they are all digest stamped. config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" } + # CSS is already compiled and prefixed by cssbundling-rails (yarn build:css), + # so disable Sprockets' Sass compressor (added by sassc-rails). Re-running + # SassC over the bundled application.css breaks on Bootstrap's url(...) assets. + config.assets.css_compressor = nil + # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.asset_host = "http://assets.example.com" diff --git a/config/resque_web.ru b/config/resque_web.ru new file mode 100644 index 0000000..8d15c7d --- /dev/null +++ b/config/resque_web.ru @@ -0,0 +1,14 @@ +# Rackup config for the Resque dashboard (Resque::Server). +# +# We run the dashboard directly via `rackup`/Puma instead of the `resque-web` +# binary, because resque 2.7's WebRunner relies on the old `Rack::Handler` API +# that was removed in Rack 3. +# +# bundle exec rackup -o 0.0.0.0 -p 5678 config/resque_web.ru +require "resque" +require "resque/server" + +Resque.redis = ENV.fetch("REDIS_URL", "redis://localhost:6379/0") +Resque.redis.namespace = ENV.fetch("RESQUE_NAMESPACE", "resque:boxrunner") + +run Resque::Server.new From 3e4f7c2185e474d0347fb576cf6b607e64a5ed0f Mon Sep 17 00:00:00 2001 From: Jie Chen Date: Fri, 12 Jun 2026 13:35:26 -0500 Subject: [PATCH 7/7] run bin/rubocop autocorrect --- Gemfile | 2 +- config/initializers/resque.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index acf9221..50ff427 100644 --- a/Gemfile +++ b/Gemfile @@ -76,7 +76,7 @@ gem "arclight" group :development, :test do gem "solr_wrapper", ">= 0.3" - gem 'rspec-rails', '~> 8.0' + gem "rspec-rails", "~> 8.0" end gem "rsolr", ">= 1.0", "< 3" gem "bootstrap", "~> 5.3" diff --git a/config/initializers/resque.rb b/config/initializers/resque.rb index 9cd0db2..6b8dee4 100644 --- a/config/initializers/resque.rb +++ b/config/initializers/resque.rb @@ -3,4 +3,4 @@ require "resque" Resque.redis = ENV.fetch("REDIS_URL", "redis://localhost:6379/0") -Resque.redis.namespace = "resque:boxrunner" \ No newline at end of file +Resque.redis.namespace = "resque:boxrunner"