项目拆解之 sidekiq

前提:

SendMessageWorker 生成一条消息发送给用户,消息内容生成强依赖在 proj_A 上的 models 中的方法

想要做

proj_A 上的 sidekiq worker 解耦到 proj_B

如何错误地做

把相关的 models 方法复制 proj_B 上,在 proj_B 上创建一个 SendMessageWorker,删除 proj_A 上的 SendMessageWorker,完毕!(这样做相当于没有解耦,反倒增加了引入 BUG 的可能:相同的知识应该只有一处权威的表达)

如何正确地做

# proj_A

class SendMessageWorker
  include Sidekiq::Worker
  sidekiq_options queue: :default, pool: `proj_B_redis`

  def perform(options = {})
  end
end
# proj_B

class SendMessageWorker
  include Sidekiq::Worker
  sidekiq_options queue: :default, pool: `proj_B_redis`

  def perform(options = {})
    # TODO: send message to user
  end
end

proj_A 仅做为任务的生产者,让 proj_B 的 sidekiq 去消费任务

其实也可以不保留 proj_A 中的 SendMessageWorker,直接塞任务到 proj_B_redis

require 'redis'
require 'json'

class RedisJobPusher
  def self.send_message_worker(user_id, title, message)
    params = [user_id, title, message]
    RedisJobPusher.push_to_queue('SendMessageWorker', params)
  end

  def self.push_to_queue(worker_name, params)
    # using <<  rather than + because it cats instead of newing up string objects
    redisurl = 'redis://' << CONFIG[:redis_server] << ':6379' << '/' << CONFIG[:redis_db_num]

    msg = { 'class' => worker_name, 'args' => params, 'retry' => true }
    redis = Redis.new(:url => redisurl)
    redis.lpush("raisemore_sidekiq:queue:JobWorker", JSON.dump(msg))
  end
end