我已经创建了一个自定义上传/服务机制来管理流星应用的媒体文件。
整个应用程序在~800 - 4000(因系统而异)文件被提供给浏览器后挂起
var idx = 0;
var send = Meteor.npmRequire('send');
WebApp.connectHandlers.use(function(req, res /*, next*/ ) {
sendFile(req, res, '/penken.jpg');
});
var sendFile = function(req, res, urlPath) {
var lidx = idx++;
console.log(lidx, 'requesting', urlPath);
send(req, urlPath, {
root: process.env.PWD + '/.uploads',
maxAge: 20 * 60 * 1000
}).pipe(res);
};
meteor
问题,还是send
,WebApp
等。有趣的是,如果我使用以下bash行运行wget 10000次:
for i in `seq 10000`; do wget http://localhost:3000/uploads/penken.jpg -qO /dev/null; sleep 0.01; done
问题不会表现出来
在https://github.com/albertmatyi/meteor-hangs
找到它git clone https://github.com/albertmatyi/meteor-hangs.git
cd meteor-hangs
meteor
http://localhost:3000/
F5
,Ctrl + R
或Cmd + R
)
控制台将显示请求和提供资源的时间答案 0 :(得分:1)
这个可能发生是因为您使用的是具有阻塞文件I / O操作的中间件。对于每个页面加载,Meteor最初必须通过每个中间件处理程序并在可以提供页面之前运行它。
您可能遇到此问题的原因是您正在执行的操作是I / O密集型,并且在等待上一个任务完成时阻止其他中间件运行。 (请记住,javascript是异步的,但文件I / O是阻塞的。)
通过这种方式并不容易。想到的直接想法是以某种方式使用内存缓冲区或其他东西,或确保它只针对特定路径运行(例如/upload
而不是所有路径。这样你就不会感到不方便了得多。
wget操作的原因是没有其他调用的javascript。对于每个页面加载meteor,它拥有浏览器将调用的每个模块的几十个javascript文件(反过来每个文件请求也会调用middlware)。它将在页面提供之前等待js。
为了简单起见,我建议的是,如果路线与特定模式(例如sendFile
)匹配,则仅执行/upload
操作。这样,如果您使用http://localhost:3000
,则无法运行。
有点像这样(只适用于/upload
var url = Npm.require('url');
WebApp.connectHandlers.use(function(req, res, next) {
var path = url.parse(req.url).pathname;
if(path != '/upload') next()
sendFile(req, res, '/penken.jpg');
});