如何在before_update上反映过程?

时间:2018-05-14 14:09:03

标签: ruby-on-rails ruby ruby-on-rails-4

我有一个项目,当我尝试更新某个属性时,会运行一个耗时且耗尽的before_update函数。此函数运行一些脚本,当它们成功完成时,属性会更改。

问题是我想要一种方法来反映当前正在运行的脚本的当前状态(显示某种2/5 ... 3/5 ...过程),但我无法想象解决方案。我尝试在DB中保存最后一个运行命令,但由于脚本在before_update范围内运行,因此只有在所有脚本完成后才能完成提交。

这种问题有没有优雅的解决方案?

1 个答案:

答案 0 :(得分:1)

通常,您应该避免在回调中运行昂贵的交叉代码。如果您想在不运行该代码的情况下更新其中一条记录,那么您将开始添加标志以确定何时应该运行该回调,以及各种其他的恶意。此外,如果在请求期间更新记录,则昂贵的回调代码将减慢整个请求的速度,并可能超时和/或阻止其他访问者访问您的应用程序。

构建此方法的方法是首先创建记录(可能带有一个标记/状态,告诉应用程序的其余部分,更新尚未经过处理"然而 - 意味着目前在你的回调中的相关代码还没有运行)。然后,您将一个后台作业排入队列,该作业可以执行回调中的任何操作。如果您使用的是Sidekiq,则可以使用sidekiq-status gem来更新作业的状态。

然后,您将添加一个控制器/操作,用于检查作业的状态并以JSON形式返回,还有一些JS会每隔几秒钟执行一次该操作以检查作业的状态并相应地更新您的界面。

即使您不想根据作业状态更新您的用户,也可能在此处按顺序执行后台作业 - 特别是如果该代码非常昂贵,或涉及第三方API调用。如果没有,它可能属于控制器,您可以在事务中运行它。但是,如果您需要更新您的用户的工作状态,那么后台工作就可以了。