Geçenlerde Sidekiq ile çalışmaya başladı ve uzun zamandır arıyordum müthiş bir özellik olduğunu fark: Ben gerek kalmazRuby on Rails + Sidekiq: Zamanlanmış bir iş başlangıç saatini nasıl değiştirebilirim?
UserMailer.delay_until(5.days.from_now).find_more_friends_email
Temelde gelecekte bir iş zamanlayabilirsiniz benim Yeni bir etkinlik için bir başlangıç zamanı ile sürekli anket uygulaması.
Şimdi bu bir cazibe gibi çalışır, ama nasıl bir iş başlangıç zamanı değiştirebilirim? Çoğu zaman zamanlanmış bazı etkinlikler başlangıç saatlerini değiştirir. Bunu sidekiq'de nasıl kopyalarım? Sadece başlangıç zamanını değiştirmek için
ben işi silmek ve yeni bir tane oluşturabilirsiniz biliyorum ama bu mümkün mü?
DÜZENLEME: Burada Oto Brglez fikri üzerine inşa edilmiş ve
belgelenmiş kod şudur: Şimdi eğer
module TaskStuff
class TaskSetter
include Sidekiq::Worker
sidekiq_options retry: false
def perform(task_id)
task = Task.find(task_id)
# Get the worker that's performing this job
if worker = AppHelpers.find_worker(jid)
# If the worker matches the "at" timestamp then this is the right one and we should execute it
if worker.last["payload"]["at"].to_s.match(/(\d*\.\d{0,3})\d*/)[1] == task.start.to_f.to_s.match(/(\d*\.\d{0,3})\d*/)[1]
task.execute
else
custom_logger.debug("This worker is the wrong one. Skipping...")
end
else
custom_logger.error("We couldn't find the worker")
end
end
end
end
module AppHelpers
[...]
def self.find_worker(jid)
Sidekiq::Workers.new.select {|e| e.last["payload"]["jid"] == jid}.first
end
[...]
end
> task = Task.create(start: 5.hours.from_now)
> TaskStuff::TastSetter.perform_at(task.start, task.id)
görev idam alacak bu
> task.update_attributes(start: 4.hours.from_now)
> TaskStuff::TastSetter.perform_at(task.start, task.id)
4 saat ve diğer iş (5 saat içinde gerçekleştirilecek) zamana ulaştığında yok sayılacak ve kaldırılacaktır.
Başlangıçta worker.last["payload"]["at"]
yerine Time.now
kullanmayı denedim, ancak zamanlanmış bir iş her zaman zamanında yürütülmeyeceğinden dolayı oldukça yanlış olabilirdi. 15 saniyelik bir kontrol aralığı vardır ve tüm işçiler başka yerlerde meşgulse, iş daha da gecikebilir.
task.start
okunurken farklı bir ondalık sayıya sahip bir float almam ve koşulun geçmemesi nedeniyle Regexp
kullanmak zorunda kaldım. Bu şekilde, her iki değeri de 3 ondalık olarak alıyorum.
ben buldum almanın tek yolu işinin niteliği görevlisi aracılığıyla bunu almak gereğidir "at". Eğer Redis'e sorsaydım ya da Mike'ın Sidekiq::ScheduledSet.new
'unu kullanacak olsaydım, şu anki işi alamazdım çünkü Redis'ten çoktan çekilmiş olurdu.
DÜZENLEME 2: ilgilenen herkes için
, ben de benzer ancak farklı bir yaklaşımla gitti. Temel olarak, Task
'un başlangıç zamanını karşılaştırmak yerine, modele ve start_token
adlı Sidekiq çağrısına fazladan bir alan ekledim. Eğer sidekiq işi nesnenin sahip olduğu aynı belirteçle çağrılmışsa, aksi halde işi atın ve atın. Model, start_time modelini her değiştirdiğinde jeton güncellenir.
ikinci düzenleme doğrultusunda ve İşimle içinde bir ActiveRecord nesnesi kullanıyorum olarak olanlar için bu, yardımcı olabilir, ben updated_at alanını kullanıyorum. ActiveRecord kimliğimle işime aktarıyorum ve işim başladığında, updated_at'ın hala aynı olup olmadığını kontrol ediyorum – phyzalis