[String] job_name The name of the job # @param [Time] time The time at which the job was cleared by the scheduler # # @return [Boolean] true if the job was registered, false otherwise def self.register_job_instance(job_name, time) job_key = pushed_job_key(job_name) registered, _ = Sidekiq.redis do |r| r.pipelined do r.zadd(job_key, time.to_i, time.to_i) r.expire(job_key, REGISTERED_JOBS_THRESHOLD_IN_SECONDS) end end registered end ruby/2.7.0/gems/sidekiq-scheduler-3.1.0/lib/sidekiq-scheduler/redis_manager.rb ジョブが重複しない制御があるのでは? • Sidekiq-scheduler(gem) ◦ Redisに一意なキーを作成(zadd) ◦ 成功したらキューイング
Sidekiq(gem) ◦ エンキュー ◦ 成功したらRedisからキーを削除(zrem) 二重起動の原因を調べる def enqueue_jobs(now=Time.now.to_f.to_s, sorted_sets=SETS) Sidekiq.redis do |conn| sorted_sets.each do |sorted_set| while job = conn.zrangebyscore(sorted_set, '-inf', now, :limit => [0, 1]).first do if conn.zrem(sorted_set, job) Sidekiq::Client.push(Sidekiq.load_json(job)) Sidekiq::Logging.logger.debug { "enqueued #{sorted_set }: #{job}" } end end end end end ruby/2.7.0/gems/sidekiq-5.2.10/lib/sidekiq/scheduled.rb
Sidekiq(gem) ◦ エンキュー ◦ 成功したらRedisからキーを削除(zrem) これらを踏まえると。 ➔エンキュー後重複ジョブをキューイング可能。 (ジョブの起動とか完了は関係なかった) 二重起動の原因を調べる def enqueue_jobs(now=Time.now.to_f.to_s, sorted_sets=SETS) Sidekiq.redis do |conn| sorted_sets.each do |sorted_set| while job = conn.zrangebyscore(sorted_set, '-inf', now, :limit => [0, 1]).first do if conn.zrem(sorted_set, job) Sidekiq::Client.push(Sidekiq.load_json(job)) Sidekiq::Logging.logger.debug { "enqueued #{sorted_set }: #{job}" } end end end end end ruby/2.7.0/gems/sidekiq-5.2.10/lib/sidekiq/scheduled.rb