Rails / Heroku - 如何为需要文件上载的进程创建后台作业

时间:2014-07-31 18:45:24

标签: ruby-on-rails heroku amazon-s3 carrierwave delayed-job

我在Heroku上运行我的Rails应用程序。我有一个管理仪表板,允许通过自定义CSV上传器批量创建新对象。最终我将上传10k-35k行的CSV。解析器在我的开发环境中完美运行,通过上传CSV成功创建了20k +条目。但是,在Heroku上,我遇到了H12错误(请求超时)。这显然是有道理的,因为文件太大而且创建了很多对象。为了解决这个问题,我尝试了一些简单的解决方案,在Heroku上放大了dyno功能,并将CSV文件减少到2500行。这些都没有成功。

我尝试将我的delayed_job实现结合使用将worker dyno添加到我的proc文件到.delay文件上传和处理,以便web请求不会超时等待文件处理。但是,这会失败,因为此后台进程依赖于CSV上载,该上载在Web请求时保留在内存中,因此后台作业在执行时没有该文件。

似乎我可能需要做的是

  1. 执行CSV上传到S3作为后台进程
  2. 将CSV文件的处理安排为后台作业
  3. 确保CSV解析器知道如何在S3上找到该文件
  4. 解析并完成
  5. 此解决方案并非100%理想,因为上传文件的管理员用户实际上会收到“确定,您已发送说明”确认,而无法清楚地了解流程是否正常执行。但是如果能完成工作,我可以处理并稍后修复。

    tl;博士问题

    假设上述解决方案是正确/推荐的方法,我该如何正确地构建它?我大多不清楚如何安排/创建一个delayed_job条目,知道在哪里可以找到通过Carrierwave上传到S3的CSV文件。任何和所有的帮助非常感谢。

    请索取任何有用的代码。

2 个答案:

答案 0 :(得分:1)

我主要使用sidekiq对heroku上的异步进程进行排队。

This link也是一个很好的资源,可以帮助您开始使用heroku实现sidekiq。

答案 1 :(得分:1)

您可以将需要处理的文件放在特定的S3存储桶中,无需将文件名传递给后台作业。

后台作业可以从特定的s3存储桶中获取文件并开始处理。

要向用户提供实时更新,您可以执行以下操作:

  1. 使用memcached来维护状态。后台作业应该不断更新状态信息。如果您不熟悉缓存,可以使用db表。

  2. 在用户响应中包含javascript / jquery。此脚本应发出ajax请求以获取状态信息并在线提供用户更新。但如果它是一个大文件,用户可能不想等待作业完成,在这种情况下,最好提供一个查询界面来检查作业状态。

  3. 后台作业应在完成时从存储桶中删除/移动文件。

  4. 在我们的应用程序中,我们允许用户导入多个模型的数据并开发通用设计。我们在db中维护状态信息,因为我们对它进行了一些分析。如果您有兴趣,这里有一篇描述我们设计的博客文章http://koradainc.com/blog/。该设计没有描述后台进程或S3,但结合上述步骤应该为您提供完整的解决方案。