Ruby Sidekiq在运行时导致StackLevelTooDeep错误

Ruby Sidekiq在运行时导致StackLevelTooDeep错误,ruby,ruby-on-rails-3,sidekiq,Ruby,Ruby On Rails 3,Sidekiq,这是我的Sidekiq设置: 调用我的后台进程的控制器 BackgroundStatCalculator.perform_async @game.athlete.id, @game.id, current_athlete_sport.id Sidekiq工人: class BackgroundStatCalculator include Sidekiq::Worker def perform(user_id, game_id, sport_id) sport = Sport.

这是我的
Sidekiq
设置:

调用我的后台进程的控制器

BackgroundStatCalculator.perform_async @game.athlete.id, @game.id, current_athlete_sport.id
Sidekiq工人:

class BackgroundStatCalculator
  include Sidekiq::Worker

  def perform(user_id, game_id, sport_id)
    sport = Sport.find sport_id
    sport.stat_type_categories.each do |st_cat|
      calc = "StatCalculators::#{st_cat.name}".constantize.new(user_id, game_id)
      calc.run_calculations
    end
  end
end
计算器:

module StatCalculators
  class Passing
    def initialize(user_id, game_id)
      @user = User.find(user_id)
      @game = Game.find(game_id)
    end

    def save_completion_percentage
      completions = Stat.for_type("Completions").for_user(@user).sum(:float_value)
      attempts = Stat.for_type("Pass Attempts").for_user(@user).sum(:float_value)
      value = completions/attempts
      stat = Stat.new(value: value, game_id: @game.id, athlete_id: @user.id, float_value: value)
      stat.save(validate: false)
    end

    def run_calculations
      klass = self.class
      klass.instance_methods(false).each do |method|
        klass.instance_method(method).bind(self).call
      end
    end
  end
end
堆栈跟踪:

2013-06-07T17:55:34Z 73625 TID-ov6v51sww BackgroundStatCalculator JID-5bab7cec30523a4b12dd6438 INFO: fail: 5.155 sec
2013-06-07T17:55:34Z 73625 TID-ov6v51sww WARN: {"retry"=>true, "queue"=>"default", "class"=>"BackgroundStatCalculator", "args"=>[58, 68, 6], "jid"=>"5bab7cec30523a4b12dd6438", "error_message"=>"stack level too deep", "error_class"=>"SystemStackError", "failed_at"=>"2013-06-07T17:42:01Z", "retry_count"=>5, "retried_at"=>2013-06-07 17:55:34 UTC}
2013-06-07T17:55:34Z 73625 TID-ov6v51sww WARN: stack level too deep
2013-06-07T17:55:34Z 73625 TID-ov6v51sww WARN: /Users/dennismonsewicz/.rvm/gems/ruby-1.9.3-p429/gems/sidekiq-2.7.4/lib/sidekiq/processor.rb:88
由于某种原因,当调用
.perform\u async
时,它不只是执行一次就完成了。。。它将100行转储到我的数据库中


以前有人碰到过这个问题吗?我对Sidekiq的使用还比较陌生,因此我为我的无知道歉

您创建了一个无限的调用循环,导致堆栈溢出

您的
run\u calculations
方法调用其所在对象上的每个实例方法,其中包括
run\u calculations
。您需要从列表中筛选出此方法,或者更好的是,找到一种只列出您要调用的计算方法的方法。可能会使用类似“calculate_”的前缀


同步运行作业时是否会发生这种情况?也就是说,你能用
BackgroundStatCalculator复制这个问题吗?新建
perform\u async
use
perform
,而不是在实例上使用
perform
。它只在调用
perform\u async
时工作正常。它将100条记录转储到数据库中,你能发布回溯吗?好的,我重新启动了rails服务器,不再出现
StackLevelTooDeep
问题。。。由于某种原因,它只是将100条记录转储到我的数据库中。。。同样,当
.perform
正在检查您的redis队列时,不会发生这种情况。它可能有一些工作备份。
module StatCalculators
  class Passing
    def initialize(user_id, game_id)
      ...
    end

    def calculate_completion_percentage
       ...
    end

    def run_calculations
      klass = self.class
      calculation_methods = klass.instance_methods(false).select do |method|
         method.to_s.match /calculate_/
      end
      calculation_methods.each do |method|
        klass.instance_method(method).bind(self).call
      end
    end
  end
end