【问题标题】:How can I stop active record callbacks from throwing an error when they fail?如何阻止活动记录回调在失败时抛出错误?
【发布时间】:2021-03-04 13:07:04
【问题描述】:

我有一个 Rails 应用程序,其中包含一些 after_save 活动记录回调,它们负责更新第二个缓存数据库。

最近我遇到了一些负载问题,第二个数据库响应缓慢或拒绝连接,我的用户在尝试保存对象时开始收到 500 错误。

我认为这归咎于我误解了回调的工作原理 - 我假设通过制作这些 after_save 而不是 before_save,用户是“安全的”,如果回调失败,那将是优雅和沉默的。

当这些回调失败时,我如何重构我的代码以阻止这种行为并避免让我的用户看到错误消息?

我已经研究过重构回调以简单地触发活动作业,如下所示:

# models/mymodel.rb

after_save :update_index

def update_index
    UpdateIndexJob.perform_later(self)
end

活动作业包括实际更新第二个缓存数据库的逻辑。

我不确定是否还需要实现 sidekiq 和 redis 才能使其正常工作。

我还阅读了关于 rails observers 的文章,它的工作方式显然类似于回调,但在它们失败时不会中断请求-响应周期。

【问题讨论】:

  • 你能包括一些日志吗?

标签: ruby-on-rails ruby activerecord redis sidekiq


【解决方案1】:

如何阻止活动记录回调在失败时抛出错误?

这是一个非常开放的问题,我想你已经自己回答了。

您可以:

  1. 重写它,使其不会失败(例如,仅调用后台任务)。
  2. 挽救异常。 (但是,中止代码路径实际上是一个明智的决定吗?!可能不是。)

我已经研究过重构回调以简单地触发活动作业 [...] 我不确定是否还需要实现 sidekiq 和 redis 才能使其工作。

这似乎是一个安全的实现。 是的,您需要配置后端才能实际执行作业。见the documentation。 Sidekiq、Resque、Sneakers、Sucker Punch、Queue Classic、Delayed Job 和 Que 只是其中的一部分。

我还阅读了有关 Rails 观察者的文章...

这也可以防止用户出错,但是如果由于间歇性超时而失败会发生什么?后台作业的核心功能之一是它们重试失败。

因此,我建议为此使用后台作业而不是观察者。


现在说了这么多,我们几乎没有谈到你要解决什么问题

更新第二个缓存数据库

您几乎没有说过“第二个缓存数据库”实际上是什么,但我怀疑这实际上可以配置为leader/follower database,并且完全位于您的应用程序之外。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-10
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多