keylimetoolbox / resque-kubernetes

Run Resque (and ActiveJob) workers as Kubernetes Jobs and autoscale from 0!
MIT License
54 stars 15 forks source link

ArgumentError: wrong number of arguments (given 4, expected 5) #14

Closed izhilenkov closed 6 years ago

izhilenkov commented 6 years ago

Running resque job with resque-kubernetes gem giving following error - ArgumentError: wrong number of arguments (given 4, expected 5) from lib/jobs/some_import_job.rb:8:inenqueue_to' `

jeremywadsack commented 6 years ago

Hi @izhilenkov. Thank you for reporting this issue. Could you provide more context or backtrace for the error you are getting?

I'm trying to figure out where that could have been called from within the gem. Resque#enqueue_to takes a variable number of arguments that are passed to the callbacks. The callback in resque-kubernetes doesn't care how many arguments are passed, so I'm confused as to where the error is percolating from. More stack details would allow me to help you narrow this down.

izhilenkov commented 6 years ago

Hi @jeremywadsack ! Thanks for fastest response! So we use rescue as a rails job Sample code is:

class Jobs::SomeJob
  extend Resque::Plugins::Retry
  extend Resque::Kubernetes::Job
  QUEUE_NAME = :integration
  @queue = QUEUE_NAME
  def self.enqueue_to(integration, full_integration=false)
    Resque.enqueue_to(@queue, self, integration.id, full_integration)
  end

  def self.perform(integration_id, full_integration=false)
    integration = Integration.find(integration_id)
    Integration::Some::Services::ImportService.new(integration).process(full_integration)
  end

  def job_manifest
     # manifest
  end
end

I call the job from service like

integration.update_attributes!(status: :in_queue)
Jobs::SomeJob.enqueue_to(integration, @full_integration)

With resque-kubernetes gem I got the error above, without it, it's working as well. Run within k8s cluster, from another pod. k8s cluster based on GKE

Stack: resque (1.27.4) resque-kubernetes (0.9.0) resque-retry (1.5.2) resque-scheduler (4.3.1) resque-web (0.0.12) resque_mailer (2.4.3) Ruby 2.4.2 Rails 5.2.0

izhilenkov commented 6 years ago

I downgraded to 0.6.0 and after issue with default clusterRole it's working. Seems something is going wrong on 0.7.0 version. P.S. It would be cool to add which role to use to create jobs or/and add to readme about default ClusterRoleBinding

jeremywadsack commented 6 years ago

@izhilenkov Thanks for the details. The only difference between 0.6 and 0.7 is the change to support kubeclient 3.x. However, it looks like you had the problem with 0.9? Did you also reproduce the issue with 0.7?

I think I'm still missing some context though. It sounds like the error isn't the call to Resque.enqueue_to but perhaps somewhere deeper in the stack? Is there additional stack trace that shows resque-kubernetes, resque, or some other gem? I still don't understand how Resque.enqueue_to can raise that error.

I created a test case using the code you have above and was able to enqueue a job in a cluster without that error. Is it possible you can produce a very small code sample that reproduces this?

I'm not sure if this is related, but in the documentation for Resque.enqueue_to is does state that "queue should be the String name of the queue you're targeting." In the example code you show, you are sending a symbol.

Can you open a separate issue and provide details about the issue you are having with "default" clusterRole? Or if you know what needs to be fixed a pull request would be really helpful. I'm not very familiar with roles in Kubernetes.

izhilenkov commented 6 years ago

Full stack trace is

ArgumentError: wrong number of arguments (given 4, expected 5)
    from lib/jobs/job.rb:11:in `enqueue_to'
    from app/models/model.rb:27:in `run'
    from app/services/runner.rb:16:in `process_integration'
    from app/services/runner.rb:8:in `block in call'
    from app/services/runner.rb:7:in `call'
    from (irb):2

Yes, I reproduced the issue since 0.7.0 I replaces symbol with string, but it's still raise the same error.

jeremywadsack commented 6 years ago

@izhilenkov Thank you for sticking with this. I appreciate all the work you already did to try to isolate the issue.

I'm really confused about that stack trace because your ::enqueue_to method only takes 1 or 2 arguments. It seems like that's an exception from deeper in the stack somewhere but that for whatever reason the stack is lost. You don't happen to have a construct like this in Job.enqueue_to do you?

begin
  ...
resque => e
  raise e # Remove the `e` to raise to original error and keep the full stack trace
end

I've seen missing stack depth before but I'm not sure why it happens.

On the assumption that we can't get more stack trace to pinpoint I've looked again at the code changes between resque-kubernetes 0.6 and 0.7. There are no changes to any code within the gem — the only changes that affect code at all are that 0.7 allows kubeclient 3.x as well as 2.2.

As I can't reproduce this could you help by testing with resque-kubernetes 0.7.0 and kubeclient 2.5.2? If that doesn't fail, then try kubeclient 3.x (3.1.2 should be fine).

izhilenkov commented 6 years ago

After downgrading of kubeclient to 3.1.2, the 0.9.0 is working fine

jeremywadsack commented 6 years ago

Thanks for the update, @izhilenkov.

The gemspec requires kubeclient < 4.0 and I don't see a kubeclient version after 3.1.2 that isn't 4.0.0.

Which version of kubeclient was it failing with?

izhilenkov commented 6 years ago

I'm sorry for confusing, I downgrade it in Gemfile and Gimefile.lock, but version 2.5.2 is remaining in dependencies. so, I tested it with 3.1.2 again, and it's failing in the same way.

jeremywadsack commented 6 years ago

@izhilenkov I was able to reproduce this using kubeclient 3.1.2 back to 3.1.0. This error does not happen in 3.0.0. I'm not sure why but at one point I got no stack trace (as you did, I think) and then later was able to get the stack trace.

The issue is a breaking change to Kubeclient::Config::Context#initialize in kubeclient (it's not a documented interface).

I will try to get a PR out to fix this today. I might just require kubeclient 3.1.2 (and possibly support 4.0.0) as I'd like to also take advantage of the better support in kubeclient 3.1.2 for reading credentials from within a cluster and remove the special handling code here that caused the error.

jeremywadsack commented 6 years ago

For the record this is resolved with either v0.10.0 or v1.1.0, both released to rubygems. The former pins kubeclient to <= 3.0.0 and is the simple upgrade path. The latter requires kubeclient >= 3.1.2 and includes other significant changes.