diff --git a/demo/.gitignore b/demo/.gitignore new file mode 100644 index 0000000..74094e8 --- /dev/null +++ b/demo/.gitignore @@ -0,0 +1,2 @@ +log +tmp diff --git a/demo/Gemfile b/demo/Gemfile new file mode 100644 index 0000000..f1e71bf --- /dev/null +++ b/demo/Gemfile @@ -0,0 +1,8 @@ +source 'https://rubygems.org' + +gem 'rails' +gem 'sinatra' +gem 'celluloid' +gem 'launchy' +gem 'sidekiq-limit_fetch' + diff --git a/demo/README.md b/demo/README.md new file mode 100644 index 0000000..5aabe03 --- /dev/null +++ b/demo/README.md @@ -0,0 +1,2 @@ +To test effect of limits run: `rake demo:limits` +To change simulation see `lib/tasks/demo.rake` diff --git a/demo/Rakefile b/demo/Rakefile new file mode 100644 index 0000000..70b7427 --- /dev/null +++ b/demo/Rakefile @@ -0,0 +1,6 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require File.expand_path('../config/application', __FILE__) + +Demo::Application.load_tasks diff --git a/demo/app/workers/fast_worker.rb b/demo/app/workers/fast_worker.rb new file mode 100644 index 0000000..bb4b60d --- /dev/null +++ b/demo/app/workers/fast_worker.rb @@ -0,0 +1,8 @@ +class FastWorker + include Sidekiq::Worker + sidekiq_options queue: :fast + + def perform + sleep 0.2 + end +end diff --git a/demo/app/workers/slow_worker.rb b/demo/app/workers/slow_worker.rb new file mode 100644 index 0000000..9551a5e --- /dev/null +++ b/demo/app/workers/slow_worker.rb @@ -0,0 +1,8 @@ +class SlowWorker + include Sidekiq::Worker + sidekiq_options queue: :slow + + def perform + sleep 1 + end +end diff --git a/demo/config.ru b/demo/config.ru new file mode 100644 index 0000000..5bc2a61 --- /dev/null +++ b/demo/config.ru @@ -0,0 +1,4 @@ +# This file is used by Rack-based servers to start the application. + +require ::File.expand_path('../config/environment', __FILE__) +run Rails.application diff --git a/demo/config/application.rb b/demo/config/application.rb new file mode 100644 index 0000000..d9e9d6a --- /dev/null +++ b/demo/config/application.rb @@ -0,0 +1,28 @@ +require File.expand_path('../boot', __FILE__) + +# Pick the frameworks you want: +# require "active_record/railtie" +require "action_controller/railtie" +require "action_mailer/railtie" +require "sprockets/railtie" +# require "rails/test_unit/railtie" + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(:default, Rails.env) + +module Demo + class Application < Rails::Application + # Settings in config/environments/* take precedence over those specified here. + # Application configuration should go into files in config/initializers + # -- all .rb files in that directory are automatically loaded. + + # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. + # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. + # config.time_zone = 'Central Time (US & Canada)' + + # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. + # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] + # config.i18n.default_locale = :de + end +end diff --git a/demo/config/boot.rb b/demo/config/boot.rb new file mode 100644 index 0000000..3596736 --- /dev/null +++ b/demo/config/boot.rb @@ -0,0 +1,4 @@ +# Set up gems listed in the Gemfile. +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) + +require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) diff --git a/demo/config/environment.rb b/demo/config/environment.rb new file mode 100644 index 0000000..56916e7 --- /dev/null +++ b/demo/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require File.expand_path('../application', __FILE__) + +# Initialize the Rails application. +Demo::Application.initialize! diff --git a/demo/config/environments/development.rb b/demo/config/environments/development.rb new file mode 100644 index 0000000..6a7f397 --- /dev/null +++ b/demo/config/environments/development.rb @@ -0,0 +1,27 @@ +Demo::Application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + + # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. + config.assets.debug = true +end diff --git a/demo/lib/tasks/demo.rake b/demo/lib/tasks/demo.rake new file mode 100644 index 0000000..f564f7f --- /dev/null +++ b/demo/lib/tasks/demo.rake @@ -0,0 +1,57 @@ +namespace :demo do + task limit: :environment do + puts '=> Creating sidekiq tasks' + + 100.times do + SlowWorker.perform_async + FastWorker.perform_async + end + + run_sidekiq_monitoring + run_sidekiq_workers config: <<-YAML + :verbose: false + :concurrency: 4 + :queues: + - slow + - fast + :limits: + slow: 1 + YAML + end + + def with_sidekiq_config(config) + whitespace_offset = config[/\A */].size + config.gsub! /^ {#{whitespace_offset}}/, '' + + puts "=> Use sidekiq config:\n#{config}" + File.write 'config/sidekiq.yml', config + yield + ensure + FileUtils.rm 'config/sidekiq.yml' + end + + def run_sidekiq_monitoring + require 'sidekiq/web' + Thread.new do + Rack::Server.start app: Sidekiq::Web, Port: 3000 + end + sleep 1 + Launchy.open 'http://127.0.0.1:3000/workers?poll=true' + end + + def run_sidekiq_workers(options) + require 'sidekiq/cli' + cli = Sidekiq::CLI.instance + + %w(validate! boot_system).each do |stub| + cli.define_singleton_method(stub) {} + end + + with_sidekiq_config options[:config] do + config = cli.send :parse_config, 'config/sidekiq.yml' + Sidekiq.options.merge! config + end + + cli.run + end +end