perl - 如何编写在 HTTP 响应发送到客户端后运行的 Plack 中间件?
问题描述
我的 Plack Web 服务通过与 fluentD 的 TCP 连接进行日志记录,我想在将响应发送回客户端后执行我的日志记录代码。这将减少响应时间(假设这是一个高请求量服务,值得进行这种性能优化)。
至少有一个其他的 web 框架,用于 nodejs,通过允许中间件向请求对象添加一个端事件处理程序来支持这一点。我查看了Plack::Request和Plack::Response接口,但没有看到类似的事件挂钩。
我想我可能会在我的中间件中对finalize方法进行本地覆盖,以强制框架在响应完成后进行日志记录,但如果可能的话,我想避免修改 Plack 内部。
是否有更好的方法可以将某些代码的执行推迟到向客户端发送响应之后?
解决方案
感谢LeoNerd和 ilmari 在MagNET 中的调试帮助#io-async
。
#!/usr/bin/env -S plackup -s Net::Async::HTTP::Server
use Future::AsyncAwait;
use Time::HiRes qw(time);
use Future::IO qw();
use Future::IO::Impl::IOAsync qw();
async sub mylogger {
# simulate expensive run-time
await Future::IO->sleep(1);
open my $log, '>>', '/tmp/so-58605156.log';
$log->say(time);
}
my $app = sub {
my ($env) = @_;
mylogger->retain;
return [200, ['Content-Type' => 'text/plain'], [time]];
};
推荐阅读
- azure - 确保存在标记并以 cva_ 开头,用于 Azure 中的所有资源
- excel - 当 WSH.Popup 等待一定时间时,Msgbox 未关闭
- css - 有没有办法去除阴影,或者强制 vuetify 菜单与屏幕左侧完全对齐?
- javascript - 无法从另一个函数(在全局范围内定义)访问变量(数组)
- jquery - 如何使用jquery触发datagrid中的下拉列表
- animation - 如何使用 Godot 中的动画播放器跳到动画中的某个位置?
- forms - 如何将输入发送到 servlet 但不从动作发送?
- react-native - React Native:如何完全删除 Instabug?
- python-3.x - 迭代列表中的矩阵在 numpy 中停止
- node.js - 是否可以抑制 NPM 对其正在运行的命令的回显?