├── .gitignore
├── Gemfile
├── README.md
├── app
├── controllers
│ └── sidekiq_sandbox_controller.rb
├── helpers
│ └── sidekiq_sandbox_helper.rb
├── views
│ └── sidekiq_sandbox
│ │ └── index.html.erb
└── workers
│ └── sandbox_worker.rb
├── config
├── locales
│ ├── en.yml
│ └── ja.yml
├── routes.rb
└── sidekiq.yml.example
├── init.rb
├── lib
└── redmine_sidekiq
│ ├── admin_constraint.rb
│ ├── configure.rb
│ └── rails.rb
└── test
├── functional
└── sidekiq_sandbox_controller_test.rb
└── test_helper.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | /config/*.yml
2 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | gem 'sidekiq'
2 | gem 'sinatra'
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Redmine Sidekiq
2 | ===============
3 |
4 | Background jobs will use the [Sidekiq](https://github.com/mperham/sidekiq) on Redmine.
5 | You can Monitoring easily used by [Sidekiq plugin](http://www.redmine.org/plugins/redmine_sidekiq).
6 |
7 | ## Features
8 |
9 | * Administrator can use the Sidekiq Web UI from the top menu.
10 | * Add to autoload_paths of the Plugin `/app/workers`.
11 | * IMPORTANT: Anyone trying to use the sidekiq `:delay` method, use `:sidekiq_delay` instead because for former has clashes with Redmine safe attributes. There is NO change for `:delay_for` and `:delay_until` methods.
12 |
13 | ## Installation
14 |
15 | ```
16 | $ git clone https://github.com/ogom/redmine_sidekiq ./plugins/redmine_sidekiq
17 | $ bundle install
18 | ```
19 |
20 | ## Usage
21 |
22 | ### Worker
23 |
24 | Add worker classes in `/plugins/[your plugin]/app/workers`.
25 |
26 | ```
27 | class HardWorker
28 | include Sidekiq::Worker
29 | def perform(name, count)
30 | # do something
31 | end
32 | end
33 | ```
34 |
35 | ### Sidekiq Web UI
36 |
37 | It appears in the top menu.
38 |
39 | 
40 |
41 |
42 | ## Example
43 |
44 | Example of Sidekiq worker.
45 |
46 | ```
47 | ./plugins/redmine_sidekiq/app/workers/sandbox_worker.rb
48 | ```
49 |
50 | ### Sandbox Web UI
51 | Enqueue from the Web UI.
52 |
53 | ```
54 | http://[redmine]/sidekiq/sandbox
55 | ```
56 |
57 | Enqueue, click the `perform_async(*args)` of the Jobs.
58 |
59 | 
60 |
61 |
62 | ### CLI
63 |
64 | Enqueue from the command line.
65 |
66 | ```
67 | $ bin/rails runner 'SandboxWorker.perform_async'
68 | ```
69 |
70 | ## License
71 |
72 | * MIT
73 |
--------------------------------------------------------------------------------
/app/controllers/sidekiq_sandbox_controller.rb:
--------------------------------------------------------------------------------
1 | class SidekiqSandboxController < ApplicationController
2 | unloadable
3 | before_filter :require_admin
4 |
5 | def index
6 | @stats = Sidekiq::Stats.new
7 | end
8 |
9 | def perform_async
10 | name = params['name']
11 | count = params['count']
12 | jid = SandboxWorker.perform_async(name, count)
13 | flash[:notice] = "Enqueued job id: #{jid}" if jid
14 | redirect_to :action => 'index'
15 | end
16 |
17 | def perform_in
18 | interval = params['interval'].to_i ||= 2
19 | jid = SandboxWorker.perform_in(interval.minute)
20 | flash[:notice] = "Enqueued job id: #{jid}" if jid
21 | redirect_to :action => 'index'
22 | end
23 |
24 | def perform_at
25 | interval = params['interval'].to_i ||= 2
26 | jid = SandboxWorker.perform_at(interval.minute.from_now)
27 | flash[:notice] = "Enqueued job id: #{jid}" if jid
28 | redirect_to :action => 'index'
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/app/helpers/sidekiq_sandbox_helper.rb:
--------------------------------------------------------------------------------
1 | module SidekiqSandboxHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/views/sidekiq_sandbox/index.html.erb:
--------------------------------------------------------------------------------
1 |
<%= l :sidekiq %>
2 | Sandbox
3 |
4 |
5 |
6 | Stats
7 |
8 | stats = Sidekiq::Stats.new
9 |
10 | Gets the number of jobs that have been processed.
11 | stats.processed # => <%= @stats.processed %>
12 |
13 | The number of jobs that have failed.
14 | stats.failed # => <%= @stats.failed %>
15 |
16 | The queues with name and number enqueued.
17 | stats.queues # => <%= @stats.queues %>
18 |
19 | The number of jobs enqueued in all queues (does NOT include retries and scheduled jobs).
20 | stats.enqueued # => <%= @stats.enqueued %>
21 |
22 |
23 |
24 | Jobs
25 |
26 | The standard.
27 | <%= link_to('perform_async(*args)', sidekiq_sandbox_perform_async_path, method: :post) %>
28 |
29 | The Scheduled Jobs by interval.
30 | <%= link_to('perform_in(interval, *args)', sidekiq_sandbox_perform_in_path(interval: 1), method: :post) %>
31 |
32 | The Scheduled Jobs by timestamp.
33 | <%= link_to('perform_at(timestamp, *args)', sidekiq_sandbox_perform_at_path(interval: 1), method: :post) %>
34 |
35 | The job will fail.
36 | <%= link_to('perform_async()', sidekiq_sandbox_perform_async_path(name: :failed), method: :post) %>
37 |
--------------------------------------------------------------------------------
/app/workers/sandbox_worker.rb:
--------------------------------------------------------------------------------
1 | class SandboxWorker
2 | include Sidekiq::Worker
3 | sidekiq_options retry: 2
4 |
5 | def perform(name=nil, count=nil)
6 | puts 'Doing sandbox work'
7 | raise 'Failed sandbox work' if name == 'failed'
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | en:
2 | sidekiq: Sidekiq
3 |
--------------------------------------------------------------------------------
/config/locales/ja.yml:
--------------------------------------------------------------------------------
1 | ja:
2 | sidekiq: Sidekiq
3 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | require 'sidekiq/web'
2 | require 'redmine_sidekiq/admin_constraint'
3 |
4 | RedmineApp::Application.routes.draw do
5 | mount Sidekiq::Web => '/sidekiq', :constraints => RedmineSidekiq::AdminConstraint.new
6 |
7 | match '/sidekiq/sandbox', to: 'sidekiq_sandbox#index', via: :get
8 | match '/sidekiq/sandbox/perform_async', to: 'sidekiq_sandbox#perform_async', via: :post
9 | match '/sidekiq/sandbox/perform_in', to: 'sidekiq_sandbox#perform_in', via: :post
10 | match '/sidekiq/sandbox/perform_at', to: 'sidekiq_sandbox#perform_at', via: :post
11 | end
12 |
--------------------------------------------------------------------------------
/config/sidekiq.yml.example:
--------------------------------------------------------------------------------
1 | production:
2 | redis:
3 | url: redis://localhost:6379/8
4 | namespace: mynamespace
5 |
--------------------------------------------------------------------------------
/init.rb:
--------------------------------------------------------------------------------
1 | $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/lib"
2 |
3 | require 'redmine_sidekiq/configure'
4 | require 'redmine_sidekiq/rails'
5 |
6 | Redmine::Plugin.register :redmine_sidekiq do
7 | name 'Redmine Sidekiq plugin'
8 | description 'This is a Sidekiq plugin for Redmine'
9 | version '2.1.0'
10 | url 'https://github.com/ogom/redmine_sidekiq'
11 | author_url 'mailto:ogom@hotmail.co.jp'
12 | author 'ogom'
13 |
14 | menu :top_menu, :sidekiq, '/sidekiq', :if => Proc.new {User.current.admin}
15 | end
16 |
--------------------------------------------------------------------------------
/lib/redmine_sidekiq/admin_constraint.rb:
--------------------------------------------------------------------------------
1 | module RedmineSidekiq
2 | class AdminConstraint
3 | def matches?(request)
4 | return false unless request.session[:user_id]
5 | user = User.find request.session[:user_id]
6 | user && user.admin?
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/lib/redmine_sidekiq/configure.rb:
--------------------------------------------------------------------------------
1 | require 'sidekiq'
2 |
3 | # Enable extensions if sidekiq version > 4
4 | if Sidekiq::Extensions.respond_to?(:enable_delay!)
5 | Sidekiq::Extensions.enable_delay!
6 | end
7 |
8 | module RedmineSidekiq
9 | class Configure
10 | file = File.join(::Rails.root, 'plugins/redmine_sidekiq/config/sidekiq.yml')
11 | if File.exist?(file)
12 | config = YAML.load_file(file)[::Rails.env]
13 | redis_conf = config['redis'].symbolize_keys
14 | end
15 |
16 | Sidekiq.configure_server do |config|
17 | config.redis = redis_conf if redis_conf
18 | end
19 |
20 | Sidekiq.configure_client do |config|
21 | config.redis = redis_conf if redis_conf
22 | end
23 |
24 | Sidekiq::Extensions::ActiveRecord.module_eval do
25 | remove_method :delay if respond_to?(:delay)
26 | end
27 |
28 | Sidekiq::Extensions::ActionMailer.module_eval do
29 | remove_method :delay if respond_to?(:delay)
30 | end
31 |
32 | Sidekiq::Extensions::Klass.module_eval do
33 | remove_method :delay if respond_to?(:delay)
34 | end
35 |
36 | Sidekiq.remove_delay! if Sidekiq.methods.index(:remove_delay!)
37 |
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/lib/redmine_sidekiq/rails.rb:
--------------------------------------------------------------------------------
1 | module RedmineSidekiq
2 | class Rails
3 | Dir.glob(File.join(Redmine::Plugin.directory, '*')).sort.each do |directory|
4 | if File.directory?(directory)
5 | workers = File.join(directory, 'app', 'workers')
6 | if File.directory?(workers)
7 | ActiveSupport::Dependencies.autoload_paths += [workers]
8 | end
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/test/functional/sidekiq_sandbox_controller_test.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../../test_helper', __FILE__)
2 |
3 | class SidekiqSandboxControllerTest < ActionController::TestCase
4 | # Replace this with your real tests.
5 | def test_truth
6 | assert true
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | # Load the Redmine helper
2 | require File.expand_path(File.dirname(__FILE__) + '/../../../test/test_helper')
3 |
--------------------------------------------------------------------------------