Rails 控制器 - Return 然后执行复杂的操作(没有工人)

Rails Controller - Return and then perform complex action (without worker)

我想在我的应用程序中创建一个 API 端点,它获取数据并使用它执行复杂、耗时的操作,但仅 after return正在收到数据。

例如,我希望能够做这样的事情:

def action
  render json: { data_received: params[:whatever].present? }
  perform_calculations( params[:whatever] )
end

不幸的是,据我了解,Ruby/Rails 是同步的,并且需要控制器操作 endrender/redirect /head 某种声明。

通常情况下,我会考虑使用后台工作者来完成此操作,例如:

 def action
   DelayedJobActionPerformer.perform_later(params[:whatever])
   render { data_received: params[:whatever].present? }
 end

但是,一个工人(在 Heroku 上)每月为这样一个初级应用程序花费相当多的钱,我正在寻找替代方案。除了后台工作人员之外,您是否可以考虑从操作中 return 然后 然后 执行该行为?

我正在考虑创建一个单独的 Node 应用程序或可以 启动一个动作然后响应的东西,但这感觉很荒谬。我想我脑海中的架构将涉及一个执行大部分行为的主要 Rails 应用程序,以及一个充当 API 端点的轻量级 Node 应用程序,它可以接收请求,响应它已经收到,然后发送要由第一个 Rails 应用程序或其他应用程序执行的数据。但这感觉太过分了,也像是把问题推到一边。

不管怎样,不管我最后是要买一个工人还是几个工人,我很想知道这种事情是否可行,以及是否使用外部 API 作为准-worker 是有道理的(特别是考虑到打破应用程序问题的普遍趋势)。

不是真的...

那么你可以创建一个新线程:

thread = Thread.new { perform_calculations( params[:whatever] ) }

并且不调用 thread.join,但这是非常不可靠的,因为如果主线程终止,该线程将被杀死。

我不知道 Heroku 中 cron 作业的情况如何,但另一种选择是让 table 有待处理的作业,你可以在其中保存 params[:whatever] 并触发 rake 任务使用 cron 定期检查和执行任何未决任务。这个解决方案是一个(真正的)基本工人实施。

听说过sucker_punch,你可以试一试。这将 运行 在单个 web 进程中,但缺点是如果重新启动 web 进程并且还有尚未处理的作业,它们将会丢失。因此不推荐用于关键的后台任务。