我可以使用与axlsx_rails HTTPstream,以避免与大/时间密集型查询超时问题?

我在Rails 4.2.5中使用了axlsx_rails Ruby gem来生成一个Excel文件,让用户下载他们的数据。

我有这在我的index.xlsx.axlsx模板:

wb = xlsx_package.workbook wb.add_worksheet(name: 'Transactions') do |sheet| sheet.add_row ["Date", "Vendor Name", "Account", "Transaction Category", "Amount Spent", "Description"] @transactions.find_each(batch_size: 100) do |transaction| sheet.add_row [transaction.transaction_date, transaction.vendor_name, transaction.account.account_name, transaction.transaction_category.name, transaction.amount, transaction.description] end end 

如果有足够的数据,则在返回Excel文件之前页面超时。 有没有一种方法可以使用HTTPstream发送结果,因为它正在处理,而不是等到整个transactions.find_each循环完成?

我在这里看到了使用response.stream.write的代码:

 response.headers['Content-Type'] = 'text/event-stream' 10.times { response.stream.write "This is a test message" sleep 1 } response.stream.close 

这种方法看起来很有希望,但我不知道如何将response.stream.write集成到axlsx_rails模板中。 有没有办法?

这是我的第一个堆栈溢出的问题,道歉的任何失礼,并感谢您提供任何想法。

即使你可以stream,我不认为这会更快。 问题是,Axlsx在完成构build之前不会生成电子表格。 而axlsx_rails只是包装了这个过程,所以也没有帮助。 因此,不会有部分电子表格可以提供服务,延迟时间也会一样长。

你应该咬下子弹,尝试Sidekiq (这是非常快)或其他一些工作调度。 然后,您可以立即返回请求并在后台生成电子表格。 您将不得不做一些监视或通知来获取生成的报告,或者使用JavaScript转发到另一个url,当转换完成时设置标志,转发到新页面。 你的电话在那里。

有一个工作日程安排程序也非常方便,当你需要发送一封电子邮件回应一个请求; 响应可以立即返回,而不是等待电子邮件完成。 一旦你有一个调度程序,你会发现更多的用途。

如果您select一个作业调度程序,axlsx_rails将允许您使用您的模板生成附件 ,或者您可以创build自己的视图上下文来生成该文件 。 或者对于渲染模板的一个真正的骨头的方式, 看看这个testing 。

欢迎来到SO,Joe。

我在评论中问,但也许最好回答和解释。

简单的答案是肯定的,如果你可以渲染的话,你总是可以进行stream式处理(尽pipe有时会有不同的性能结果)。

然而,如果你直接引用一个文件,它不会工作。 IE, http://someurl.com/reports/mycustomreport.xlsx

在rails中stream式处理并不是这样默认的。 但是不用担心,你应该仍然能够解决你的问题,只要你想保存的时间只是渲染。

在您的控制器中(*注意将来,当您询问渲染操作时,有助于提供您的控制器操作代码*),您应该可以执行类似的操作:

 def report @transactions = current_user.transactions.all respond_to do |format| format.html { render xlsx: 'report', stream: true} end end 

可能有助于对您的加载进行完整性检查。 在你的日志中作为200响应的一部分,你应该得到如下的东西:

在506ms内完成200行(查看:494.6ms | ActiveRecord:2.8ms)

如果活动logging号太高或高于视图号,则此解决scheme可能无法用于您的查询,并且如所build议的那样,这可能需要被线程化或发送到作业。