【发布时间】:2015-07-28 00:24:58
【问题描述】:
我正在创建一个大型 CSV 响应的 Perl 模块的一部分。服务器在 Plack 上运行,我在这方面还不是专家。
目前我正在使用这样的东西来发送响应:
$res->content_type('text/csv');
my $body = '';
query_data (
parameters => \%query_parameters,
callback => sub {
my $row_object = shift;
$body .= $row_object->to_csv;
},
);
$res->body($body);
return $res->finalize;
但是,query_data 函数不是一个快速的函数,并且会检索很多记录。在那里,我只是将每一行连接到 $body 中,并且在处理完所有行之后,发送整个响应。
我不喜欢这个有两个明显的原因:首先,在$body 被销毁之前需要大量内存。其次,在该方法完成工作并实际使用$res->body($body) 发送响应之前,用户看不到响应活动。
我试图找到这个in the documentation 的答案,但没有找到我需要的东西。
我还尝试在我的回调部分调用$res->body($row_object->to_csv),但似乎最终只发送了我对$res->body 的最后一次调用,覆盖了之前的所有调用。
有没有办法发送 Plack 响应来刷新每一行的内容,以便用户在收集数据时开始实时接收内容,而不必先将所有数据累积到一个可验证的位置?
提前感谢任何 cmets!
【问题讨论】:
-
我没有尝试过,但您应该可以使用带有
getline方法的对象。有关更多详细信息,请发布一个简短但完整的示例。 -
谢谢思南。是的,您提到的是正确的,我尝试了一个实现
getline的简单对象,它工作正常,除了Plack 仍在缓冲响应并且在->getline未定义之前不会向浏览器发送任何内容。关于我的示例,我对其进行了修改以使其更加不言自明。发布我的真实代码的唯一真正区别是添加了许多不相关的行。我唯一想弄清楚的是如何让 Plack 发送无缓冲/自动刷新的响应。 -
您的代码中没有
get_data函数。我想你的意思是query_data。 -
发布一个简短但完整的示例可以让您减少我为尝试可能的解决方案所做的工作。