Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delayed Job + Octopus 0.10.2 issues on Rails 5.2 (undefined method `any?' for nil:NilClass) #552

Open
lunaru opened this issue May 21, 2020 · 2 comments

Comments

@lunaru
Copy link

lunaru commented May 21, 2020

It looks like Delayed Job and Octopus are not happy with each other out of the box. I know both are fairly common gems used by the Rails community so I thought I'd go ahead and log an issue here with a collection of workarounds cobbled together from various other documented issues.

In particular, it looks like forking in general is a problem and documented here: #489 and here: #511 but these are documented as Puma issues, when in fact it's true for delayed_job as well.

In addition, there is also a shard selection issue documented here: #241

In case anyone wanders into this Issue, here's initializer that I've put together that seems to fix things:

# from this: https://github.com/tchandy/octopus/issues/241
# this prevents delayed job from pulling from the wrong shard
module Delayed
  module Backend
    module ActiveRecord
      class Job < ::ActiveRecord::Base
        class << self
          alias_method :reserve_without_octopus, :reserve

          def reserve(worker, max_run_time = Worker.max_run_time)
            Octopus.using(:master) do
              reserve_without_octopus(worker, max_run_time)
            end
          end
        end
      end
    end
  end
end

# from this: https://github.com/thiagopradi/octopus/issues/489
# and also this: https://github.com/thiagopradi/octopus/issues/511
# Forking in DJ seems to cause issues with the connections
module Octopus
  class Proxy
    alias_method :safe_connection_without_fork_check, :safe_connection

    def safe_connection_with_fork_check(connection_pool)
      retries ||= 0
      safe_connection_without_fork_check(connection_pool)
    rescue NoMethodError => e
      ActiveRecord::Base.establish_connection
      ActiveRecord::Base.connection.initialize_shards(Octopus.config)
      retry if (retries += 1) < 2
    end

    alias_method :safe_connection, :safe_connection_with_fork_check

    def connected?
      retries ||= 0
      shards.any? { |_k, v| v.connected? }
    rescue NoMethodError
      proxy_config.reinitialize_shards
      retry if (retries += 1) < 2
    end
  end
end
@brentkearney
Copy link

Upgrading a Rails 5.1 system to 5.2, and encountered this issue. Switching to @mikwat's fork seems to solve it.

@jakeonfire
Copy link

jakeonfire commented Aug 8, 2022

i was having an issue with unicorn which also uses forking. a much simpler solution in that case is to use its after_fork hook to re-establish octopus connections:

# config/unicorn.rb
after_fork do |server, worker|
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.establish_connection
    ActiveRecord::Base.connection.initialize_shards(Octopus.config) if Octopus.enabled?
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants