【问题标题】:Rails debounce delayed job background task? removing duplicatesRails debounce延迟作业后台任务?删除重复项
【发布时间】:2018-10-28 03:41:39
【问题描述】:

去抖动是一种将函数/作业推迟到特定时间后执行的常用方法。

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

Delayed_Job

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

Sidekiq

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

【问题讨论】:

  • 在 RabbitMQ 中,我使用死信交换。

标签: ruby-on-rails sidekiq delayed-job


【解决方案1】:

做自己也不错。

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 分钟等),让用户继续采取行动。如果你在 1 秒后运行你的工作,他们很可能会继续采取行动并再次触发。

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

【讨论】:

  • 我不确定,但我的猜测是执行 delete_all 查询将导致数据库引擎仍需要执行数据库查找(类似于 select...where)。在包含数千(或数万)条记录的大型数据库上的序列化列(长字符串)上执行此操作可能非常慢。如果这是使用可以很好索引的作业的唯一密钥或签名完成的,那么这将是一个好方法。
【解决方案2】:

我要做的是安排一个定期任务,假设每 5 分钟检查一次是否有人​​需要通知。是的,这似乎是一项昂贵的操作,但对于您的用例,我(目前)看不到其他解决方案。因此,假设您有 10 个使用聊天的用户。您可以每 5 分钟检查一次是否有用户没有看到某些消息,如果是,则仅当他们在 N 分钟后处于非活动状态时才通知他们。

要安排此类任务,您可以使用crono gem。检查这个answer

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

Crono.perform(CheckUsersToBeNotifiedJob).every 5.minutes

【讨论】:

    【解决方案3】:

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

    它使用另一个表来跟踪作业并可以限制和去抖动。

    【讨论】:

      猜你喜欢
      • 2016-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-04
      • 1970-01-01
      • 2019-08-13
      相关资源
      最近更新 更多