Rails debounce 延迟作业后台任务?删除重复项

Rails debounce delayed job background task? removing duplicates

Debouncing 是一种将 function/job 推迟到特定时间后才执行的常用方法。

用例: 多个用户进行的活跃聊天对话,他们不应为每条键入的消息都收到电子邮件通知。但很可能在静默几分钟后,如果消息未读,用户应该会看到一条通知。

Delayed_Job

无解,有相关问题:https://github.com/collectiveidea/delayed_job/issues/72

Sidekiq

https://github.com/hummingbird-me/sidekiq-debounce

我会做的是安排一个周期性任务,假设每 5 分钟检查一次是否有人​​必须得到通知。是的,这似乎是一项昂贵的操作,但对于您的用例,我(目前)看不到其他解决方案。假设您有 10 个使用聊天的用户。每 5 分钟您可以检查是否有用户没有看到某些消息,如果是,您仅在他们在 N 分钟内不活动时通知他们。

要安排此类任务,您可以使用 crono gem. Check this answer

Crono 让您可以做这样的事情:

Crono.perform(CheckUsersToBeNotifiedJob).every 5.minutes

如果您使用延迟作业作为活动作业的实现,请查看 'activejob-trackable' gem。 https://github.com/ignatiusreza/activejob-trackable

它使用另一个 table 来跟踪作业并可以节流和去抖动。

做自己也不错

class AdminJob
  def self.debounce(job, args={})
    handler = YAML.dump(job)
    count = Delayed::Job.where(handler: handler).where('locked_at IS NULL').delete_all
    Rails.logger.info("deleted: #{count} jobs")
    Delayed::Job.enqueue(job, args)
  end
end

而不是写作:

Delayed::Job.enqueue(YourJobName.new(account_id), {run_at: 10.minutes.from_now})

你现在写:

AdminJob.debounce(YourJobName.new(account_id), {run_at: 10.minutes.from_now})

延迟作业在 YAML 中序列化您的作业参数,然后将其作为 handler 保存到数据库中。因此,如果您连续调用 AdminJob.debounce(...) 10 次,它将在每次之前删除。

确保给自己时间(5.minutes,等等)让用户继续采取行动。如果你在 1 秒后 运行 你的工作,他们很可能会继续采取行动并再次触发。

是的,我在 3 年后回答我自己的问题...