是否可以将Block或Procs作为参数发送给Sidekiq?

时间:2013-01-31 22:28:10

标签: ruby-on-rails ruby sidekiq

我有一个标准系统,用于对各种数据集执行计算。什么是伟大的是我可以将这些计算作为Proc传递给perform方法。这就是我想要完成的事情:

class Calculator
    include Sidekiq::Worker

    def perform rails_model , rails_model_id
         obj = Kernel.const_get( rails_model ).find( rails_model_id )
         yield( obj )
    end
end

Calculator.perform_asyc( "User" , 123 , { |u| u.do_something } )

这种事情是可能的还是不好的做法?我知道直接发送对象是不好的做法,所以我假设发送块也是一个坏主意?

2 个答案:

答案 0 :(得分:4)

这是不可能的。 Ruby中的代码没有序列化格式,仅用于数据。

答案 1 :(得分:3)

实际上,你可以做到这一点。我需要一个工作人员对一组记录执行某些操作,但我希望能够灵活地更改模型上的查询,以便在需要时返回不同的集合。

class MyWorker
  include Sidekiq::Worker

  def perfom(scoping_query)
    MyModel.class_eval(scoping_query).call.find_each do |m|
     # do stuff...
    end
  end    
end

MyWorker.perform_async("proc { where(attribute: value) }")

我的解决方案将适用于您的示例。

class Calculator
  include Sidekiq::Worker

  def perform(klass, id, code_block)
    obj = klass.constantize.find(id)
    klass.constantize.class_eval(code_block).call(obj)
  end
end

Calculator.perform_asyc("User", 123, "proc { |u| u.do_something }")

正如您所看到的,诀窍是将块作为字符串发送,然后在返回Proc的类的范围内计算该字符串,然后您可以调用它。