如何在Rails中等待而不阻塞主线程?

时间:2019-04-03 08:08:32

标签: ruby-on-rails ruby

我有一个正在开发的Rails应用程序,以便当用户完成付款时,他们将被重定向到控制器A中的视图。我正在使用的付款API还希望我们实现回调URL,这由控制器B中的操作提供服务(当付款网关向该URL发送POST请求时,这将触发数据库中的付款状态设置为“已付款”)。我想知道的是,如何在控制器A中为重定向操作编写一个while循环,以检查付款状态是否已设置为“已付款”而不阻塞主线程?当我测试我的应用程序时,服务器控制台指示启动了POST请求,但是重定向时主线程被while循环阻塞,因此我的应用程序陷入了无限循环。我尝试使用Ruby Threads,但似乎无法弄清楚。

2 个答案:

答案 0 :(得分:0)

您不需要控制器A等待。为什么?付款过程可能需要几秒钟到几小时。您希望用户坐下来观看“加载页面”微调器吗?

相反,您可以在付款网关回调控制器中推进该过程(将状态设置为“已付款”,向用户发送电子邮件并开始交付商品)。

答案 1 :(得分:0)

您可以将正在运行的Rails应用视为巨大的while循环:等待请求,接收请求,处理请求,等待下一个请求。听起来您的付款处理器的设计旨在通过向您提供在控制器B中指定回调URL(也就是您的应用暴露网络钩子)的能力,与该体系结构很好地集成。如果您阻止该循环,则您的应用将停止响应新请求。

我了解您的问题与如何更新用户有关。用户完成付款后,通常会将其重定向到GET请求访问的页面,以便刷新浏览器时不会重新提交其付款(可能是POST)。假设这是一个“显示订单”操作,其中包括付款状态为“待处理”或“已处理”。当用户第一次看到该页面时,它将显示状态:未决。稍后,在付款处理器点击控制器B中的回调后,如果用户访问同一页面或在其浏览器中刷新该页面,则该页面应显示状态:已处理。

如果您希望页面自行更新,通常可以通过javascript中的轮询来完成。您可以公开来自同一操作(或仅返回订单付款状态的新操作)的JSON响应,然后在浏览器中构建运行在javascript中的循环,每隔几秒钟点击一次该操作以查看状态是否已更改,然后结束的时候。考虑到在某些情况下稍后会发生的情况,请考虑使用指数下降来快速更新状态,但是如果要花费几分钟或几小时,则可以避免对服务器的请求过多。