使用 Rails 实施计划任务执行的最佳实践?
Best practice to implement scheduled task execution with Rails?
在我的 Rails 应用程序中,用户可以取消他们的订阅,这应该会触发一个功能,将他们的帐户降级到 current_billing_period_end
(此变量由支付提供商的 API 提供).例如,用户在 4 月 12 日取消了他们的订阅,但订阅有效到 3 月 1 日。因此,该用户在数据库中的 premium
条目应仅在 3 月 1 日设置为 false
。
我已经使用 Resque 和 Resque-Scheduler 实现了一个可行的解决方案,但现在我想知道这是否有点矫枉过正?
我可以改为在取消订阅时为用户设置一个 subscription_end_date
数据库条目,并将其设置为 current_billing_period_end
,然后每当用户进行身份验证时,我都会 运行
if user.premium != false && user.subscription_end_date == Time.now.strftime("%Y-%m-%d")
user.premium = false
user.save
end
但是,这意味着 运行 每当用户进行身份验证/前端通过我的 API.
检查用户是否登录时,该片段
我的问题是:实现该功能的更好方法是什么? Resque 解决方案看起来更干净,但我想知道它是否对我在这里想要实现的目标来说太多/太费力了。我以前从未与 Resque 合作过,如果它是我不必在生产中维护的另一件事,我会很高兴。
不要那样做。
将许多作业安排在几天或几周后是一个糟糕的设计,尤其是当它们执行关键任务时。
为什么?
主要是因为预定作业的日期不存储在您的应用程序数据库中,而是存储在另一个数据库中,大部分时间在 Redis 中。在大多数情况下,它不包含在备份中。因此,当您需要恢复备份的那一天,您将丢失所有挂起的计划作业。在最后一个订阅期结束之前所有待处理的帐户可能会保持打开状态。
最安全的解决方案是依靠保存实际订阅结束日期的数据库字段。我们将其命名为subscription_ends_on
。如果您的用户在 4 月 12 日退订,您将 subscription_ends_on
设置为值“3 月 1 日”。
然后您创建一个每天午夜运行的后台作业,并取消订阅 subscription_ends_on
不为空且小于或等于今天的所有帐户。
在我的 Rails 应用程序中,用户可以取消他们的订阅,这应该会触发一个功能,将他们的帐户降级到 current_billing_period_end
(此变量由支付提供商的 API 提供).例如,用户在 4 月 12 日取消了他们的订阅,但订阅有效到 3 月 1 日。因此,该用户在数据库中的 premium
条目应仅在 3 月 1 日设置为 false
。
我已经使用 Resque 和 Resque-Scheduler 实现了一个可行的解决方案,但现在我想知道这是否有点矫枉过正?
我可以改为在取消订阅时为用户设置一个 subscription_end_date
数据库条目,并将其设置为 current_billing_period_end
,然后每当用户进行身份验证时,我都会 运行
if user.premium != false && user.subscription_end_date == Time.now.strftime("%Y-%m-%d")
user.premium = false
user.save
end
但是,这意味着 运行 每当用户进行身份验证/前端通过我的 API.
检查用户是否登录时,该片段我的问题是:实现该功能的更好方法是什么? Resque 解决方案看起来更干净,但我想知道它是否对我在这里想要实现的目标来说太多/太费力了。我以前从未与 Resque 合作过,如果它是我不必在生产中维护的另一件事,我会很高兴。
不要那样做。
将许多作业安排在几天或几周后是一个糟糕的设计,尤其是当它们执行关键任务时。
为什么?
主要是因为预定作业的日期不存储在您的应用程序数据库中,而是存储在另一个数据库中,大部分时间在 Redis 中。在大多数情况下,它不包含在备份中。因此,当您需要恢复备份的那一天,您将丢失所有挂起的计划作业。在最后一个订阅期结束之前所有待处理的帐户可能会保持打开状态。
最安全的解决方案是依靠保存实际订阅结束日期的数据库字段。我们将其命名为subscription_ends_on
。如果您的用户在 4 月 12 日退订,您将 subscription_ends_on
设置为值“3 月 1 日”。
然后您创建一个每天午夜运行的后台作业,并取消订阅 subscription_ends_on
不为空且小于或等于今天的所有帐户。