【发布时间】:2014-02-09 05:15:14
【问题描述】:
有时我需要对 writeMeLater 的 Meteor.call 进行排队并同步执行(阻止来自同一客户端的其他对 writeMeLater 的调用)。
其他时候,对writeMeLater 的调用应尽快执行,而不会排在当前排队的所有调用后面。
如果async 参数为真,以下是我使用this.unblock() 的尝试。案例 1 和 2 工作正常。但在案例 3 中,async=true 的呼叫被排在async=false 的呼叫后面!我们如何使用async=true 拨打电话跳过队列?这将类似于来自第二个客户端的呼叫在来自第一个客户端的呼叫之后不排队的方式,
所有Meteor.call() 均来自客户端
案例 1(正确同步):
Meteor.call('writeMeLater', 's', false)
Meteor.call('writeMeLater', 's', false)
Meteor.call('writeMeLater', 's', false)
案例 2(正确异步):
Meteor.call('writeMeLater', 'a', true)
Meteor.call('writeMeLater', 'a', true)
Meteor.call('writeMeLater', 'a', true)
案例 3(不是期望的行为)
Meteor.call('writeMeLater', 's', false)
Meteor.call('writeMeLater', 's', false)
Meteor.call('writeMeLater', 's', false)
Meteor.call('writeMeLater', 'a', true)
Meteor.call('writeMeLater', 'a', true)
Meteor.call('writeMeLater', 'a', true)
server/main.js
writeMeLater = function(data, callback) {
console.log('writeMeLater: ', data)
// simulate taking 3 second to complete
Meteor.setTimeout(function() {
Logs.insert({data: data, timestamp: new Date().getTime()})
console.log('Log.insert: ', data)
callback(null, 'done')
}, 3 * 1000)
}
writeMeLaterSync = Meteor._wrapAsync(writeMeLater)
Meteor.methods({
writeMeLater: function(data, async) {
if(async)
this.unblock()
writeMeLaterSync(data)
}
})
【问题讨论】:
-
@imslavko 是否可以让一些方法调用立即执行而不是排队,类似于来自不同客户端的方法调用不会在第一个客户端的调用之后排队
-
这正是
this.unblock()调用的作用——它将允许另一个方法调用当前连接到 start 之前完成前一个。这就是我看到的输出:pastebin.com/gtdgLTGf,它看起来对我来说是正确的。对于 3 次同步调用,在调用完成之前会有 3 秒的延迟。对于第二批 - 它们都同时开始并在 3 秒后结束。 -
由于您只运行一个 node.js 服务器,所有 6 个调用将共享相同的事件循环。请记住,node.js 是单线程的。没有真正的多线程,只有协作并发
-
对于真正的多线程,您需要运行多个服务器实例并对它们之间的连接负载进行负载平衡,但即便如此,一个 DDP 连接将只与一个单线程服务器通信(如 DDP是有状态的)
-
仅当客户端建立两个不同的 DDP 连接或者您的服务器上有消息队列和 node.js 服务器的多个进程时。这只是单线程 JavaScript 环境的局限。
标签: javascript multithreading node.js asynchronous meteor