Rails 在控制器中异步执行任务

2024-01-09

当我的路线中有一条路线时,我需要执行三项任务Controller叫做。现在我的代码看起来像这样(缩写):

 def set_quotas

    TaskOne.new().ex
    TaskTwo.new().ex
    TaskThree.new().ex
    
    quotas = @user.quotas
    render json: quotas, status: 200, each_serializer: Api::V1::QuotaSerializer
  end

每个任务都按顺序运行。然而,其中一些人会致电外部服务。因此,完成此调用所需的总时间最终为 4-8 秒,我们确实希望加快速度。

我想做的是同时运行所有三个任务,但要等到每个任务完成后再渲染json回复。在 Rails 中实现这一点的最佳方法是什么?


您可以使用threads https://ruby-doc.org/core-2.2.0/Thread.html为了这。

这是一个简单的解决方案:

def set_quotas
  [
    Thread.new { TaskOne.new().ex },
    Thread.new { TaskTwo.new().ex },
    Thread.new { TaskThree.new().ex }
  ].each &:join

  quotas = @user.quotas
  render json: quotas, status: 200, each_serializer: Api::V1::QuotaSerializer
end

然而,在 Ruby 中使用并发时需要注意一些事情。首先也是最重要的是,当您使用线程时,您将面临并发带来的所有复杂情况。期待头痛。并发可以很快地混淆简单的任务。例如,对于您的问题,您需要确保您的三个任务是真正独立。一项任务是否依赖于另一项任务的输出?一个有副作用吗?比如说,是否将一些数据写入后续作业所依赖的数据库?如果是这种情况,那么上述方法将不起作用,您需要弄清楚如何适应它们特定的相互依赖关系。

其次,红宝石线程是绿线 https://en.wikipedia.org/wiki/Green_threads。 (假设您使用的是 MRI Ruby,而不是 Rubinius 或 JRuby。)这意味着您只能使用 Ruby 线程来完成某些任务。幸运的是,网络请求是所做的事情之一not阻塞 ruby​​ 线程,意思是上面的解决方案will同时发出所有请求。您应该会看到此解决方案的加速效果。

最后,这在某种程度上特定于您的用例,当您的应用程序调用第三方时,通常最佳实践是将这些内容委托给工作人员。对第三方的调用很容易出错,并且向客户端返回 400 秒(如果您不小心处理错误,则返回 500 秒!) 很糟糕。最好将该工作放入队列中,并向客户端提供一个响应,该响应本质上是“收到请求,稍后再做”。

鉴于这一切,如果您发现需要比本机 ruby​​ 线程更强大的东西,请查看并发 ruby https://github.com/ruby-concurrency/concurrent-ruby gem.

@AbM 的回答提到了 Resque/DJ。如需更通用的解决方案,请查看活跃工作 http://edgeguides.rubyonrails.org/active_job_basics.html。对于某些(但不是全部)变体,请参阅ActiveJob 适配器列表 http://edgeapi.rubyonrails.org/classes/ActiveJob/QueueAdapters.html.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Rails 在控制器中异步执行任务 的相关文章

随机推荐

  • 如何从另一个应用程序访问字符串资源

    我有一个应用程序 A 和 B 应用程序 假设我在应用程序 A 中有一个字符串资源 lt string name abc gt ABCDEF lt string gt 如何从 B 中的活动访问 abc 的值 我尝试了以下方法 try Pack
  • 在 C# 中异步处理项目队列

    我正在尝试创建一个处理工作队列的系统 该系统具有以下规格 该系统有两个组件 工作分配器和工作人员 同时运行的worker数量有一个设定的上限 该上限大于一 为了避免同一任务被执行两次的问题 只有一个工作分配者 您会使用什么设计来创建这样的系
  • Windows 上 Sublime Text 2 的键盘列选择

    我一直在尝试通过 Windows 上的键盘绑定来选择列 The 默认 Windows sublime 键盘映射说 keys ctrl alt up command select lines args forward false keys c
  • 为什么 IEnumerable 会丢失更新的数据?

    你能向我解释一下为什么执行以下代码后Selected属性未更新为true The ListItem使用的类型来自System Web UI WebControls命名空间并且是一个类 不是结构 我相信FirstOrDefault函数返回对实
  • Android:以编程方式将 apk 复制到 /system/app

    我正在尝试从我的 java 代码安装系统应用程序 但到目前为止 我还没有取得任何成功 以下是我到目前为止所做的 我的设备已植根 我的 安装程序 应用程序作为系统应用程序安装 手动将其复制到 system app 我已经使用平台密钥签署了安装
  • mediaelement.js - RTMP 支持音频流?

    目前是否支持使用本机 HTML5 或 Flash 回退与 MediaElement 通过 RTMP 流式传输音频 我看到视频标签 data mejsoptions 属性中使用 flashStreamer 选项看起来像是对视频的支持 我知道你
  • 使用 Mockito-core 创建最终类的模拟?

    I 在github上找到 https github com relayr android sdk blob master tests src androidTest java io relayr ble service OnBoarding
  • GWT - 具有简单寻呼机问题的单元格

    单元格表分页行为异常 检查 GWT 的示例http gwt google com samples Showcase Showcase html CwCellTable http gwt google com samples Showcase
  • 如何在表单寄存器中添加一些文本字段(laravel 生成器 infyom)?

    我在这里阅读了教程 http labs infyom com laravelgenerator docs 5 3 installation http labs infyom com laravelgenerator docs 5 3 ins
  • 为什么视频观看速度这么慢?

    我在我的应用程序中放置了一个视频视图 它工作正常 但是当您打开页面时 它需要永远加载 缓冲 无论如何我可以解决这个问题吗 我的意思是这是一个3秒视频 加载时间应该不会太长 正确的 code package jslsoftware co nr
  • 是否可以为命名类型/结构定义相等性?

    读完一篇后相关问题 https stackoverflow com questions 20297503 slice as a key in map关于在映射中使用切片 我对 Go 中的相等性感到好奇 我知道可以覆盖equalsJava 的
  • 检测亮图像和暗图像

    我从 stackoverflow 答案中得到了这段代码来检测明亮和黑暗的图像 问题是它不起作用 我不知道为什么 例如如果我打电话 IsDark bitmap 40 0 9 this always sees the image as brig
  • 我可以在 C++ 中嵌套 try-catch 块吗?

    我可以嵌套 try catch 块吗 例如 void f try Some code try Some code catch ExceptionA a Some specific exception handling Some code c
  • 使用网络摄像头、OpenCV 和 Python 跟踪眼瞳位置

    我正在尝试建造一个可以通过基本的眼球运动来控制的机器人 我将网络摄像头对准我的脸 根据我瞳孔的位置 机器人会以某种方式移动 如果瞳孔位于眼睛的上 下 左 右角 机器人将分别向前 向后 向左 向右移动 我最初的计划是使用眼哈尔级联来找到我的左
  • 如何对多个wordpress自定义字段值进行排序?

    显示按 价格 自定义字段排序的 产品 类型的帖子 query new WP Query array post type gt product orderby gt meta value meta key gt price 如果还想按 尺寸
  • git stash save 和 git stash push 有什么区别?

    我应该什么时候使用git stash save代替git stash push反之亦然 git stash save接受一个非选项参数 隐藏消息 git stash push接受带有选项的消息 m并接受要存储的文件列表作为参数
  • 如何将用户输入转换为列表[重复]

    这个问题在这里已经有答案了 我想编写一个Python程序 要求用户输入7个数字 该输入应转换为列表并首先显示单个数字 然后显示整个列表 所以我的想法是从 for 循环开始 for a in range 1 8 number int inpu
  • Mobile Safari 文本输入宽度错误?

    看看这些屏幕截图 https i stack imgur com 1TFuj png https i stack imgur com 1TFuj png https i stack imgur com 3fukT png https i s
  • 设置 » JavaScript 的 document.title 中的 HTML 实体?

    我正在设置document title使用 JavaScript 但我找不到提供的方法 raquo 而不显示为文字文本 这是我的代码 document title Home raquo site com 如果我使用 在文档的标题标签中 它工
  • Rails 在控制器中异步执行任务

    当我的路线中有一条路线时 我需要执行三项任务Controller叫做 现在我的代码看起来像这样 缩写 def set quotas TaskOne new ex TaskTwo new ex TaskThree new ex quotas