【问题标题】:Is it possible to send Blocks or Procs as arguments to Sidekiq?是否可以将 Blocks 或 Procs 作为参数发送给 Sidekiq?
【发布时间】:2016-12-09 05:35:39
【问题描述】:

我有一个标准系统,用于对各种数据集执行计算。很棒的是我可以将这些计算作为 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 } )

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

【问题讨论】:

  • 我不确定你是否可以这样做,但不要使用内核模块,你为什么不:rails_model.constantize.find(rails_model_id)我希望传递一个块不应该是一个问题到 Sidekiq。
  • Sidekiq 在单独的机器上以单独的进程运行代码。传递块会有问题。

标签: ruby-on-rails ruby sidekiq


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    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 的类的范围内评估该字符串,然后您可以调用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多