brandonhilkert / sucker_punch

Sucker Punch is a Ruby asynchronous processing library using concurrent-ruby, heavily influenced by Sidekiq and girl_friday.
MIT License
2.65k stars 114 forks source link

Sucker_punch + Unicorn issue #129

Closed zenati closed 8 years ago

zenati commented 8 years ago

Hello,

I'm using sucker_punch (1.5.1) with unicorn (4.9.0) with preload_app = true in unicorn.conf. No job is getting called with the async method. When I set preload_app to false everything works properly.

I saw this in the Internet:

after_fork do |server, worker|
  SuckerPunch.config do
    queue name: :log_queue, worker: LogWorker, workers: 10
  end
end

But how can I adapt it to my unicorn.conf?

worker_processes 4
listen 3000
timeout 60

preload_app true
GC.copy_on_write_friendly = true if GC.respond_to?(:copy_on_write_friendly=)

before_exec do |server|
  ENV['BUNDLE_GEMFILE'] = "Gemfile"
end

before_fork do |server, worker|
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.connection.disconnect!
  end

  old_pid = "unicorn.pid.oldbin"
  if File.exists?(old_pid) && server.pid != old_pid
    begin
      Process.kill("QUIT", File.read(old_pid).to_i)
    end
  end
end

after_fork do |server, worker|
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.establish_connection
  end
end
brandonhilkert commented 8 years ago

That config was for an older version of sucker punch. That wasn't need since version 1. I have sucker punch running with an app with the following unicorn config without issue:

# If you have a very small app you may be able to
# increase this, but in general 3 workers seems to
# work best
worker_processes 2

# Load rails+github.git into the master before forking workers
# for super-fast worker spawn times
preload_app true

# Immediately restart any workers that
# haven't responded within 30 seconds
timeout 30
zenati commented 8 years ago

That's weird. It's only when I set preload_app to true that it stops working. What are other possible causes of this you may know about? Thank you.

zenati commented 8 years ago

In fact, i removed all lines and my unicorn.conf now is this:

listen 3000
preload_app false

It's only when I set preload_app to true that it stops working in this case too.

brandonhilkert commented 8 years ago

When you say it stops working, do you get any exceptions or error messages ?

zenati commented 8 years ago

No, no exceptions at all.

brandonhilkert commented 8 years ago

I can't think of a reason that would be the case. Without access to the source code, I'm not sure there's much else I can suggest.

brandonhilkert commented 8 years ago

Have you tried creating a new Rails app and including sucker punch with the same config with a basic worker to determine if it's the source code in that app?

zenati commented 8 years ago

I just did it. A very small and simple app using only unicorn and this unicorn.conf

listen 3000
preload_app false

It stops working when preload_app is true.

Here is the start command:

bundle exec unicorn_rails --env staging -c config/unicorn.conf (with or without --env staging is the same result)

Gemfile:

source 'https://rubygems.org'

gem 'rails', '4.2.4'
gem 'pg'
gem 'unicorn'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1.0'
gem 'redis'
gem 'sucker_punch', git: 'https://github.com/brandonhilkert/sucker_punch'
gem 'jquery-rails'
gem 'jbuilder', '~> 2.0'
gem 'sdoc', '~> 0.4.0', group: :doc

group :development, :test do
  gem 'byebug'
end

group :development do
  gem 'web-console', '~> 2.0'
  gem 'spring'
end

Gemfile.lock

GIT
  remote: https://github.com/brandonhilkert/sucker_punch
  revision: c17c373d2b997a9b3beb5e52ab2b7409d6905fda
  specs:
    sucker_punch (1.5.1)
      celluloid (= 0.16.0)

GEM
  remote: https://rubygems.org/
  specs:
    actionmailer (4.2.4)
      actionpack (= 4.2.4)
      actionview (= 4.2.4)
      activejob (= 4.2.4)
      mail (~> 2.5, >= 2.5.4)
      rails-dom-testing (~> 1.0, >= 1.0.5)
    actionpack (4.2.4)
      actionview (= 4.2.4)
      activesupport (= 4.2.4)
      rack (~> 1.6)
      rack-test (~> 0.6.2)
      rails-dom-testing (~> 1.0, >= 1.0.5)
      rails-html-sanitizer (~> 1.0, >= 1.0.2)
    actionview (4.2.4)
      activesupport (= 4.2.4)
      builder (~> 3.1)
      erubis (~> 2.7.0)
      rails-dom-testing (~> 1.0, >= 1.0.5)
      rails-html-sanitizer (~> 1.0, >= 1.0.2)
    activejob (4.2.4)
      activesupport (= 4.2.4)
      globalid (>= 0.3.0)
    activemodel (4.2.4)
      activesupport (= 4.2.4)
      builder (~> 3.1)
    activerecord (4.2.4)
      activemodel (= 4.2.4)
      activesupport (= 4.2.4)
      arel (~> 6.0)
    activesupport (4.2.4)
      i18n (~> 0.7)
      json (~> 1.7, >= 1.7.7)
      minitest (~> 5.1)
      thread_safe (~> 0.3, >= 0.3.4)
      tzinfo (~> 1.1)
    arel (6.0.3)
    binding_of_caller (0.7.2)
      debug_inspector (>= 0.0.1)
    builder (3.2.2)
    byebug (6.0.2)
    celluloid (0.16.0)
      timers (~> 4.0.0)
    coffee-rails (4.1.0)
      coffee-script (>= 2.2.0)
      railties (>= 4.0.0, < 5.0)
    coffee-script (2.4.1)
      coffee-script-source
      execjs
    coffee-script-source (1.9.1.1)
    debug_inspector (0.0.2)
    erubis (2.7.0)
    execjs (2.6.0)
    globalid (0.3.6)
      activesupport (>= 4.1.0)
    hitimes (1.2.3)
    i18n (0.7.0)
    jbuilder (2.3.1)
      activesupport (>= 3.0.0, < 5)
      multi_json (~> 1.2)
    jquery-rails (4.0.5)
      rails-dom-testing (~> 1.0)
      railties (>= 4.2.0)
      thor (>= 0.14, < 2.0)
    json (1.8.3)
    kgio (2.10.0)
    loofah (2.0.3)
      nokogiri (>= 1.5.9)
    mail (2.6.3)
      mime-types (>= 1.16, < 3)
    mime-types (2.6.2)
    mini_portile (0.6.2)
    minitest (5.8.1)
    multi_json (1.11.2)
    nokogiri (1.6.6.2)
      mini_portile (~> 0.6.0)
    pg (0.18.3)
    rack (1.6.4)
    rack-test (0.6.3)
      rack (>= 1.0)
    rails (4.2.4)
      actionmailer (= 4.2.4)
      actionpack (= 4.2.4)
      actionview (= 4.2.4)
      activejob (= 4.2.4)
      activemodel (= 4.2.4)
      activerecord (= 4.2.4)
      activesupport (= 4.2.4)
      bundler (>= 1.3.0, < 2.0)
      railties (= 4.2.4)
      sprockets-rails
    rails-deprecated_sanitizer (1.0.3)
      activesupport (>= 4.2.0.alpha)
    rails-dom-testing (1.0.7)
      activesupport (>= 4.2.0.beta, < 5.0)
      nokogiri (~> 1.6.0)
      rails-deprecated_sanitizer (>= 1.0.1)
    rails-html-sanitizer (1.0.2)
      loofah (~> 2.0)
    railties (4.2.4)
      actionpack (= 4.2.4)
      activesupport (= 4.2.4)
      rake (>= 0.8.7)
      thor (>= 0.18.1, < 2.0)
    raindrops (0.15.0)
    rake (10.4.2)
    rdoc (4.2.0)
    sass (3.4.18)
    sass-rails (5.0.4)
      railties (>= 4.0.0, < 5.0)
      sass (~> 3.1)
      sprockets (>= 2.8, < 4.0)
      sprockets-rails (>= 2.0, < 4.0)
      tilt (>= 1.1, < 3)
    sdoc (0.4.1)
      json (~> 1.7, >= 1.7.7)
      rdoc (~> 4.0)
    spring (1.4.0)
    sprockets (3.3.5)
      rack (> 1, < 3)
    sprockets-rails (2.3.3)
      actionpack (>= 3.0)
      activesupport (>= 3.0)
      sprockets (>= 2.8, < 4.0)
    thor (0.19.1)
    thread_safe (0.3.5)
    tilt (2.0.1)
    timers (4.0.4)
      hitimes
    tzinfo (1.2.2)
      thread_safe (~> 0.1)
    uglifier (2.7.2)
      execjs (>= 0.3.0)
      json (>= 1.8.0)
    unicorn (4.9.0)
      kgio (~> 2.6)
      rack
      raindrops (~> 0.7)
    web-console (2.2.1)
      activemodel (>= 4.0)
      binding_of_caller (>= 0.7.2)
      railties (>= 4.0)
      sprockets-rails (>= 2.0, < 4.0)

PLATFORMS
  ruby

DEPENDENCIES
  byebug
  coffee-rails (~> 4.1.0)
  jbuilder (~> 2.0)
  jquery-rails
  pg
  rails (= 4.2.4)
  sass-rails (~> 5.0)
  sdoc (~> 0.4.0)
  spring
  sucker_punch!
  uglifier (>= 1.3.0)
  unicorn
  web-console (~> 2.0)

BUNDLED WITH
   1.10.6
zenati commented 8 years ago

I think I know why it doesn't work. Here is how I call the SP worker:

ActiveSupport::Notifications.subscribe /api/ do |name, start, finish, id, payload|
  LogJob.new.async.perform configuration, hash
end

In conclusion: If LogJob is outside Notification bloc, it works with preload_app true and preload_app false If LogJob is inside Notification bloc, it only works with preload_app false

Why is that? Do you have an idea?

brandonhilkert commented 8 years ago

I don't. Where do the args configuration and hash come from?

On Tuesday, September 29, 2015, zenati notifications@github.com wrote:

I think I know why it doesn't work. Here is how I call the SP worker:

ActiveSupport::Notifications.subscribe /api/ do |name, start, finish, id, payload| LogJob.new.async.perform configuration, hash end

When the LogJob is outside the Notification bloc everything works even with preload_app true. Why is that? Do you have an idea?

— Reply to this email directly or view it on GitHub https://github.com/brandonhilkert/sucker_punch/issues/129#issuecomment-144199206 .


_Build a Ruby Gem is available! http://brandonhilkert.com/books/build-a-ruby-gem/?utm_source=gmail-sig&utm_medium=email&utm_campaign=gmail_

http://brandonhilkert.com

zenati commented 8 years ago

configuration and hash are both hashes like so:

{
  action: :log,
  content: { data: { ... } }
}
zenati commented 8 years ago

I ended up using

Thread.new {
  ...
}

Instead of SP worker and it works in all cases. Thanks for your help.