Ruby 关于动态生成类的疑问

lithium4010 · 2016年01月22日 · 最后由 lithium4010 回复于 2016年01月24日 · 2476 次阅读

在一个使用 rails 的项目中,有这么一个类,做的事情就是动态创建一个 job,来给别的系统发消息

class JobSender
  def self.mail(from:, to:, event:, message:)
    Register.find_job(from, to, event).class.perform_later(*message)
  end

  class Job < Struct.new(:name, :queue);
    def class
      begin
        self.name.constantize
      rescue NameError => e
        create_job
        retry
      end
    end

  private

    def create_job
      eval code
    end

    def code
      <<-JOB
        class #{self.name} < ActiveJob::Base
          queue_as :"#{self.queue}"
          def perform(*args); end
        end
      JOB
    end
  end

  class Register
    def self.find_job(sender, receiver, event)
      job_config = Settings.job_sender[sender][receiver][event]
      Job.new(job_config[:name], job_config[:queue])
    rescue NoMethodError
      raise "JobSender #{sender}:#{receiver}:#{event} does not registered."
    end
  end
end

settings.yml

job_sender:
  server_1:
    server_2:
      hello:
        name: HelloJob
        queue: test_queue

执行下面的代码,可以正确发送消息

JobSender.mail(from: :server_1, to: :server_2, event: :hello, message: "hello")

然而下面的代码会死循环

JobSender::Job.new("HelloJob", "test_queue").class.perform_later("hello")

这是为什么呢?

我主要不明白为什么前面的代码能够正确发送消息

def class是干嘛?

self.name.constantize 这句有错,导致一直报错,然后一直 retry,从而死循环?

把 retry 去掉呢?

#4 楼 @pathbox 关键是为什么前一句可以调用成功

需要 登录 后方可回复, 如果你还没有账号请 注册新账号