From 38b55d769fb06b5370b3745f33a83ff3ea0c0b14 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Thu, 31 May 2012 11:02:25 +0400 Subject: [PATCH 1/7] [refs #510] Add resque async workers --- .gitignore | 1 + Gemfile | 1 + Gemfile.lock | 11 +++++++++++ Rakefile | 6 ++++++ app/models/project.rb | 20 +++++++++++++++++--- 5 files changed, 36 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index ecb8b8624..ef7fd18e7 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ public/downloads/* *.swp *.tmproj .sass-cache/ +dump.rdb diff --git a/Gemfile b/Gemfile index f4bcc710b..0b4ded308 100644 --- a/Gemfile +++ b/Gemfile @@ -15,6 +15,7 @@ gem 'cancan', '~> 1.6.7' gem 'ancestry', '~> 1.2.5' gem 'paperclip', '~> 3.0.2' gem 'delayed_job_active_record', '~> 0.3.2' +gem 'resque' gem 'russian', '~> 0.6.0' gem 'highline', '~> 1.6.11' diff --git a/Gemfile.lock b/Gemfile.lock index 4b3b34f2f..50cbcd2a7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -235,6 +235,14 @@ GEM rdoc (3.12) json (~> 1.4) redcarpet (1.17.2) + redis (2.2.2) + redis-namespace (1.0.3) + redis (< 3.0.0) + resque (1.20.0) + multi_json (~> 1.0) + redis-namespace (~> 1.0.2) + sinatra (>= 0.9.2) + vegas (~> 0.1.2) rr (1.0.4) rspec (2.9.0) rspec-core (~> 2.9.0) @@ -303,6 +311,8 @@ GEM kgio (~> 2.6) rack raindrops (~> 0.7) + vegas (0.1.11) + rack (>= 1.0.0) warden (1.1.1) rack (>= 1.0) whenever (0.7.3) @@ -356,6 +366,7 @@ DEPENDENCIES rdiscount redcarpet (= 1.17.2) redhillonrails_core! + resque rr (~> 1.0.4) rspec-rails (~> 2.9.0) ruby-haml-js (~> 0.0.3) diff --git a/Rakefile b/Rakefile index 035ccba70..ae5e4f293 100644 --- a/Rakefile +++ b/Rakefile @@ -3,5 +3,11 @@ require File.expand_path('../config/application', __FILE__) require 'rake' +require 'resque/tasks' + +# This fixes connection fail with Postgres server on new fork: +task "resque:setup" => :environment do + Resque.before_fork = Proc.new { ActiveRecord::Base.establish_connection } +end Rosa::Application.load_tasks diff --git a/app/models/project.rb b/app/models/project.rb index c6501721b..61a0f10a9 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -41,12 +41,12 @@ class Project < ActiveRecord::Base after_create :attach_to_personal_repository after_create :create_git_repo - after_create {|p| p.delay(:queue => 'fork', :priority => 20).fork_git_repo unless is_root?} + after_create {|p| p.async(:fork_git_repo) unless is_root?} after_save :create_wiki after_destroy :destroy_git_repo after_destroy :destroy_wiki - after_save {|p| p.delay(:queue => 'import', :priority => 10).import_attached_srpm if p.srpm?} # should be after create_git_repo + after_save {|p| p.async(:import_attached_srpm) if p.srpm?} # should be after create_git_repo # after_rollback lambda { destroy_git_repo rescue true if new_record? } has_ancestry @@ -55,6 +55,20 @@ class Project < ActiveRecord::Base include Modules::Models::Owner + @queue = :fork_and_import + + # This will be called by a worker when a job needs to be processed + def self.perform(id, method, *args) + find(id).send(method, *args) + end + + # We can pass this any Repository instance method that we want to + # run later. + def async(method, *args) + Resque.enqueue(Project, id, method, *args) + end + + def to_param name end @@ -252,7 +266,7 @@ class Project < ActiveRecord::Base def create_git_repo if is_root? Grit::Repo.init_bare(path) - write_hook.delay(:queue => 'fork', :priority => 15) + async(:write_hook) end end From 526bdbe60f5e45510f2d17944037c29b428db634 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Thu, 31 May 2012 17:36:41 +0400 Subject: [PATCH 2/7] [refs #510] Resque sinatra app secure --- app/models/ability.rb | 2 ++ config/initializers/admin.rb | 8 ++++++++ config/routes.rb | 7 +++++++ 3 files changed, 17 insertions(+) create mode 100644 config/initializers/admin.rb diff --git a/app/models/ability.rb b/app/models/ability.rb index 03124c51e..07e5e91ff 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -27,6 +27,8 @@ class Ability else # Registered user rights if user.admin? can :manage, :all + # Resque authorize + can :manage, Resque # Protection cannot :approve, RegisterRequest, :approved => true cannot :reject, RegisterRequest, :rejected => true diff --git a/config/initializers/admin.rb b/config/initializers/admin.rb new file mode 100644 index 000000000..8ef8929ef --- /dev/null +++ b/config/initializers/admin.rb @@ -0,0 +1,8 @@ +# config/initializers/admin.rb +class CanAccessResque + def self.matches?(request) + current_user = request.env['warden'].user + return false if current_user.blank? + Ability.new(current_user).can? :manage, Resque + end +end diff --git a/config/routes.rb b/config/routes.rb index 74129a0fb..6783d2a92 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,12 @@ # -*- encoding : utf-8 -*- Rosa::Application.routes.draw do + require 'resque/server' + namespace :admin do + constraints CanAccessResque do + mount Resque::Server, at: 'resque' + end + end + devise_scope :users do get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru' end From 216b0da98e96b11b245a8a5640a96c33b50bce02 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Thu, 31 May 2012 17:50:42 +0400 Subject: [PATCH 3/7] [refs #510] Remove fork and import dj queues --- lib/recipes/delayed_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/recipes/delayed_job.rb b/lib/recipes/delayed_job.rb index b0b7dbcf1..1db2ba6df 100644 --- a/lib/recipes/delayed_job.rb +++ b/lib/recipes/delayed_job.rb @@ -2,7 +2,7 @@ Capistrano::Configuration.instance(:must_exist).load do namespace :delayed_job do def dj_queues - %w(fork import hook default) + %w(hook default) end def rails_env From 7d5893714938e42c18d3f4c0de39ed33638ba0b0 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Fri, 1 Jun 2012 16:54:58 +0400 Subject: [PATCH 4/7] [refs #510] Add resque recipes for capistrano --- config/deploy.rb | 6 ++++++ lib/recipes/resque.rb | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 lib/recipes/resque.rb diff --git a/config/deploy.rb b/config/deploy.rb index ac5e272f1..0c69a6379 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -37,6 +37,7 @@ require './lib/recipes/nginx' require './lib/recipes/unicorn' require './lib/recipes/bluepill' require './lib/recipes/delayed_job' +require './lib/recipes/resque' namespace :deploy do task :stub_xml_rpc do @@ -89,6 +90,11 @@ after "deploy:stop", "delayed_job:stop" after "deploy:start", "delayed_job:start" after "deploy:restart", "delayed_job:restart" +# Resque +after "deploy:stop", "resque:stop" +after "deploy:start", "resque:start" +after "deploy:restart", "resque:restart" + after "deploy:restart", "deploy:cleanup" namespace :rake_tasks do diff --git a/lib/recipes/resque.rb b/lib/recipes/resque.rb new file mode 100644 index 000000000..c66623d96 --- /dev/null +++ b/lib/recipes/resque.rb @@ -0,0 +1,37 @@ +# -*- encoding : utf-8 -*- +Capistrano::Configuration.instance(:must_exist).load do + namespace :resque do + task :start do + start_workers + end + + task :stop do + stop_workers + end + + task :restart do + stop_workers + start_workers + end + + def rails_env + fetch(:rails_env, false) ? "RAILS_ENV=#{fetch(:rails_env)}" : '' + end + + def start_workers + pids = Array.new + + Resque.workers.each do |worker| + pids << worker.to_s.split(/:/).second + end + + if pids.size > 0 + system("kill -QUIT #{pids.join(' ')}") + end + end + + def stop_workers + run "cd #{fetch :release_path} && QUEUE=* bundle exec rake resque:work" + end + end +end From 4fb74cdd503f03561c007bfd2b360531c6039b46 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Fri, 1 Jun 2012 17:30:11 +0400 Subject: [PATCH 5/7] [refs #510] Remove double admin namespace --- config/routes.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index 6783d2a92..f7a02d00e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,11 +1,6 @@ # -*- encoding : utf-8 -*- Rosa::Application.routes.draw do require 'resque/server' - namespace :admin do - constraints CanAccessResque do - mount Resque::Server, at: 'resque' - end - end devise_scope :users do get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru' @@ -29,6 +24,10 @@ Rosa::Application.routes.draw do end namespace :admin do + constraints CanAccessResque do + mount Resque::Server, at: 'resque' + end + resources :users do get :list, :on => :collection end From d29065a12ad121f5ba9de09d1b518e8bc5ac5edb Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Fri, 1 Jun 2012 17:58:14 +0400 Subject: [PATCH 6/7] [refs #510] Remove fork and import queues from bluepill instruction --- config/production.pill | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/production.pill b/config/production.pill index 8cee2adf1..dff582d31 100644 --- a/config/production.pill +++ b/config/production.pill @@ -4,7 +4,7 @@ app_name = ENV['APP_NAME'] || 'rosa_build' Bluepill.application(app_name) do |app| app.uid = app.gid = 'rosa' app.working_dir = "/srv/#{app_name}/current" - %w(fork import hook default).each do |queue| + %w(hook default).each do |queue| app.process("delayed_job_#{queue}_queue") do |process| process.start_grace_time = 10.seconds process.stop_grace_time = 10.seconds From 83736ac86d49d1cebb23b1f77b40126fed7fb477 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Mon, 4 Jun 2012 18:16:32 +0400 Subject: [PATCH 7/7] [refs #510] Rename recipe methods names to right variants --- lib/recipes/resque.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/recipes/resque.rb b/lib/recipes/resque.rb index c66623d96..439200e0a 100644 --- a/lib/recipes/resque.rb +++ b/lib/recipes/resque.rb @@ -18,7 +18,7 @@ Capistrano::Configuration.instance(:must_exist).load do fetch(:rails_env, false) ? "RAILS_ENV=#{fetch(:rails_env)}" : '' end - def start_workers + def stop_workers pids = Array.new Resque.workers.each do |worker| @@ -30,7 +30,7 @@ Capistrano::Configuration.instance(:must_exist).load do end end - def stop_workers + def start_workers run "cd #{fetch :release_path} && QUEUE=* bundle exec rake resque:work" end end