diff --git a/.travis.yml b/.travis.yml index c17c97dc..d38f50fd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,12 +7,6 @@ before_install: - gem install bundler - gem update bundler rvm: - - 2.0.0 - - 2.1.8 - 2.2.4 - 2.3.0 - jruby-head - - rbx-2 -matrix: - allow_failures: - - rvm: rbx-2 diff --git a/Changes.md b/Changes.md index 2bb37d84..52fdbcee 100644 --- a/Changes.md +++ b/Changes.md @@ -3,14 +3,13 @@ 4.2.0 ----------- -- Remove Sinatra dependency. Sidekiq's Web UI now uses Rack directly. +- Enable development-mode code reloading. **With Rails 5.0+, you don't need + to restart Sidekiq to pick up your Sidekiq::Worker changes anymore!** [#2457] +- **Remove Sinatra dependency**. Sidekiq's Web UI now uses Rack directly. Thank you to Sidekiq's newest committer, **badosu**, for writing the code and doing a lot of testing to ensure compatibility with many different 3rd party plugins. If your Web UI works with 4.1.4 but fails with 4.2.0, please open an issue. [#3075] -- Add support for development mode code reloading with Rails 5's new - thread-safe Interlock API. With Rails 5, you no longer need to - restart Sidekiq when making code changes locally! [#2457] - Allow tuning of concurrency with the `RAILS_MAX_THREADS` env var. [#2985] This is the same var used by Puma so you can tune all of your systems the same way: diff --git a/Gemfile b/Gemfile index e10ca14c..bdca91d3 100644 --- a/Gemfile +++ b/Gemfile @@ -1,8 +1,8 @@ source 'https://rubygems.org' gemspec +gem 'rails', '5.0.0' gem "hiredis" -gem 'rails', '~> 4.2' gem 'simplecov' gem 'minitest' gem 'minitest-utils' @@ -23,7 +23,7 @@ platforms :mri do gem 'ruby-prof' end -platforms :jruby do - gem 'jruby-openssl' - gem 'activerecord-jdbcsqlite3-adapter' -end +#platforms :jruby do + #gem 'jruby-openssl' + #gem 'activerecord-jdbcsqlite3-adapter' +#end diff --git a/lib/sidekiq.rb b/lib/sidekiq.rb index ec971606..d1d4d78f 100644 --- a/lib/sidekiq.rb +++ b/lib/sidekiq.rb @@ -31,7 +31,8 @@ module Sidekiq heartbeat: [], }, dead_max_jobs: 10_000, - dead_timeout_in_seconds: 180 * 24 * 60 * 60 # 6 months + dead_timeout_in_seconds: 180 * 24 * 60 * 60, # 6 months + reloader: proc { |&block| block.call }, } DEFAULT_WORKER_OPTIONS = { diff --git a/lib/sidekiq/cli.rb b/lib/sidekiq/cli.rb index ed251f69..09ad91d1 100644 --- a/lib/sidekiq/cli.rb +++ b/lib/sidekiq/cli.rb @@ -229,7 +229,7 @@ module Sidekiq require 'sidekiq/rails' require File.expand_path("#{options[:require]}/config/environment.rb") ::Rails.application.eager_load! - else + elsif ::Rails::VERSION::MAJOR == 4 # Painful contortions, see 1791 for discussion require File.expand_path("#{options[:require]}/config/application.rb") ::Rails::Application.initializer "sidekiq.eager_load" do @@ -237,6 +237,10 @@ module Sidekiq end require 'sidekiq/rails' require File.expand_path("#{options[:require]}/config/environment.rb") + else + require 'sidekiq/rails' + require File.expand_path("#{options[:require]}/config/environment.rb") + Sidekiq.options[:reloader] = Sidekiq::Rails::Reloader.new end options[:tag] ||= default_tag else diff --git a/lib/sidekiq/processor.rb b/lib/sidekiq/processor.rb index f14e232c..6a346907 100644 --- a/lib/sidekiq/processor.rb +++ b/lib/sidekiq/processor.rb @@ -36,6 +36,7 @@ module Sidekiq @job = nil @thread = nil @strategy = (mgr.options[:fetch] || Sidekiq::BasicFetch).new(mgr.options) + @reloader = Sidekiq.options[:reloader] end def terminate(wait=false) @@ -118,33 +119,35 @@ module Sidekiq jobstr = work.job queue = work.queue_name - ack = false - begin - job = Sidekiq.load_json(jobstr) - klass = job['class'.freeze].constantize - worker = klass.new - worker.jid = job['jid'.freeze] - - stats(worker, job, queue) do - Sidekiq.server_middleware.invoke(worker, job, queue) do - # Only ack if we either attempted to start this job or - # successfully completed it. This prevents us from - # losing jobs if a middleware raises an exception before yielding - ack = true - execute_job(worker, cloned(job['args'.freeze])) - end - end - ack = true - rescue Sidekiq::Shutdown - # Had to force kill this job because it didn't finish - # within the timeout. Don't acknowledge the work since - # we didn't properly finish it. + @reloader.call do ack = false - rescue Exception => ex - handle_exception(ex, job || { :job => jobstr }) - raise - ensure - work.acknowledge if ack + begin + job = Sidekiq.load_json(jobstr) + klass = job['class'.freeze].constantize + worker = klass.new + worker.jid = job['jid'.freeze] + + stats(worker, job, queue) do + Sidekiq.server_middleware.invoke(worker, job, queue) do + # Only ack if we either attempted to start this job or + # successfully completed it. This prevents us from + # losing jobs if a middleware raises an exception before yielding + ack = true + execute_job(worker, cloned(job['args'.freeze])) + end + end + ack = true + rescue Sidekiq::Shutdown + # Had to force kill this job because it didn't finish + # within the timeout. Don't acknowledge the work since + # we didn't properly finish it. + ack = false + rescue Exception => ex + handle_exception(ex, job || { :job => jobstr }) + raise + ensure + work.acknowledge if ack + end end end diff --git a/lib/sidekiq/rails.rb b/lib/sidekiq/rails.rb index a8f6b040..23b27376 100644 --- a/lib/sidekiq/rails.rb +++ b/lib/sidekiq/rails.rb @@ -35,5 +35,22 @@ module Sidekiq initializer 'sidekiq' do Sidekiq.hook_rails! end + + class Reloader + def initialize(app = ::Rails.application) + Sidekiq.logger.debug "Enabling Rails 5+ live code reloading, so hot!" unless app.config.cache_classes + @app = app + end + + def call + @app.reloader.wrap do + yield + end + end + + def inspect + "#" + end + end end if defined?(::Rails) end diff --git a/myapp/Gemfile b/myapp/Gemfile index 2777d0f8..495a0c87 100644 --- a/myapp/Gemfile +++ b/myapp/Gemfile @@ -1,21 +1,20 @@ source 'https://rubygems.org' +gem 'pry' +gem 'sidekiq', :path => '..' +gem 'rails', '5.0.0' + platforms :ruby do gem 'sqlite3' gem 'redis-namespace' end -platforms :jruby do - gem 'jruby-openssl' - gem 'activerecord-jdbcsqlite3-adapter' -end +#platforms :jruby do + #gem 'jruby-openssl' + #gem 'activerecord-jdbcsqlite3-adapter' +#end -gem 'rails', '~> 4.2' -gem 'sidekiq', :path => '..' #gem 'ruby-prof' #de Does not work with jruby or rbx: #de gem 'pry-byebug' - -# sidekiq-web dependencies -gem 'rack-protection' diff --git a/sidekiq.gemspec b/sidekiq.gemspec index b34449e9..624a9c36 100644 --- a/sidekiq.gemspec +++ b/sidekiq.gemspec @@ -22,5 +22,5 @@ Gem::Specification.new do |gem| gem.add_development_dependency 'redis-namespace', '~> 1.5', '>= 1.5.2' gem.add_development_dependency 'minitest', '~> 5.7', '>= 5.7.0' gem.add_development_dependency 'rake', '~> 10.0' - gem.add_development_dependency 'rails', '~> 4', '>= 3.2.0' + gem.add_development_dependency 'rails', '>= 3.2.0' end