Meteor._wrapAsync导致100%的CPU

时间:2014-07-08 14:56:35

标签: javascript node.js meteor redis node-redis

应用正在使用meteor-redis包运行redis查询,有时需要30秒才能返回100k结果。在此等待时间内,Meteor会在等待查询结果时冻结并占用100%的CPU。

var client = redis.createClient(port, url)
client.zrangebyscoreSync = Meteor._wrapAsync(client.zrangebyscore)

client.zrangebyscoreSync(['game:scores', '', '+inf'], function(err, scores) {

    _.each(scores, function(score, player) {
        var doc = { ... }
        Scores.insert(doc)
    })


})

问题:在等待redis返回庞大的数据集时,有没有让Meteor做其他事情?如果client.zrangebyscore未包含Meteor._wrapAsync,则Meteor会抛出错误

 Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.

并且跟踪将其指向行Scores.insert(doc)

1 个答案:

答案 0 :(得分:0)

一般情况下,Meteor允许其他方法运行,前提是您先运行this.unblock(),然后将这些请求转换为新光纤。

你获得100%CPU使用率的原因可能是cpu空闲光纤的类型和下面执行的任务的组合。

如果这是一个问题,你可以尝试使用Meteor.bindEnvironment,它不会使用future来等待,并且仍然使用回调来确保一切都保持畅通无阻:

client.zrangebyscore(['game:scores', '', '+inf'], Meteor.bindEnvironment(function(err, result) {
    _.each(scores, function(score, player) {
        var doc = { ... }
        Scores.insert(doc)
    })
}));

Meteor bindEnvironment几乎与Meteor._wrapAsync相同,只是它缺少等待结果的部分。看起来你没有使用这个位,因为你没有查找来自client.zrangebyscoreSync的结果。 Meteor.bindEnvironment可能更适合这种用途,它将你的回调包装在Fiber中,因此你可以在其中使用Meteor代码。