lock_expiration 未按预期工作的 Sidekiq 独特作业

Sidekiq unique jobs with lock_expiration not working as intended

我遇到了 lock_expiration 和 sidekiq 独特作业的问题。

gem 'sidekiq', '4.2.10'
gem 'sidekiq-cron', '1.2.0'
gem 'sidekiq-unique-jobs', '6.0.25'

使用 sidekiq 选项:

sidekiq_options queue: :medium, retry: 3, lock: :until_executed, lock_expiration: 120 * 60

当这个工人运行:

[1] pry(main)> HardWorker.perform_async
=> 53b93f122fddbb2ebd350332267484ea

作业完成,因为执行是一个空方法。锁发生了,即我在 redis 中看到了这个:

如果 AVAILABLE 密钥仍然存在于 redis 中,即在 5 秒 TTL 到期之前。只要我刷新该 TTL 并且该密钥存在,我就可以排队另一项工作并继续执行此操作。但是,在 5 秒之后并且该密钥过期后,在 EXISTS 密钥过期之前我无法排队另一个作业。

我希望能够在 5 秒后将另一个作业加入队列。我很确定在作业正确完成后应该删除 EXISTS 键。但这不会发生。作业可以入队,但只能在 AVAILABLE 键的 TTL 内。

我正在从一个非常旧的版本升级 sidekiq。这是我在不升级系统其他主要部分的情况下所能做到的。

我的问题是,这是有意为之的行为吗?基于我们已经完成的升级和配置属性的替换。它应该像以前一样工作。 IE。能够在完成当前作业后排队作业。

假设这是一个错误或预期的行为。我怎样才能得到这种行为?

我相信你的理解是正确的,一旦调用了 worker 的 perform 方法,锁就会被清除(基于文档中 until_executed 策略描述的语义).如果这没有发生,您可能遇到了错误。

然而,sidekiq-unique-jobs 的版本 6.x 被其作者描述为 "the worst mistake I ever made as a software engineer" (https://github.com/mhenrixon/sidekiq-unique-jobs/issues/553#issuecomment-732719189) and "not stable" (https://github.com/mhenrixon/sidekiq-unique-jobs/issues/553#issuecomment-733151792)。我建议至少升级到 7.x,然后再尝试解决此问题。

(或者,如果可以的话,Sidekiq Enterprise 会提供独特的作业支持,根据我的经验,这表明它本身是有效的防弹软件。)