我如何模拟多个同步的慢流星发布?
How do I simulate multiple simultaneous slow Meteor publications?
我想模拟多个慢速订阅。客户端同时订阅两个或多个发布,结果稍后到达。
目标是能够看到网络延迟和随机性如何影响我的应用程序(它会出错,因为我希望一个发布先于另一个发布,...)。
对发布使用以下简短设置:
// server/foo.js
Meteor.publish('foo', function() {
console.log('publishing foo');
Meteor._sleepForMs(2000);
console.log('waking up foo');
this.ready();
});
// server/bar.js is the same with a different name
Meteor.publish('bar', function() {
console.log('publishing bar');
Meteor._sleepForMs(2000);
console.log('waking up bar');
this.ready();
});
如 this amazing answer 中所见,由于 Meteor._sleepForMs
,两个出版物都变慢了。
然后客户端订阅每个发布:
Meteor.subscribe('bar'); // /client/bar.js
Meteor.subscribe('foo'); // /client/foo.js
从那里我希望首先看到两个 'publishing'
日志,然后是 'waking up'
.
然而,这出现在控制台中:
15:37:45? publishing bar
15:37:47? waking up bar
15:37:47? publishing foo
15:37:49? waking up foo
(我像那天一样去掉了一些无关紧要的绒毛)
很明显它 运行 是同步的。我认为有两件事可能导致这种情况:服务器 waitForMs
会完全阻塞服务器(相当奇怪),或者客户端订阅设计。
为了确保它不是服务器,我添加了一个简单的检测信号:
Meteor.setInterval(function() { console.log('beep'); }, 500);
而且它没有停止哔哔声,所以服务器没有完全阻塞。
因此我怀疑问题出在客户端订阅模型中,它可能会等待订阅准备就绪后再调用另一个..?
因此,两个问题:
- 为什么我的实验 运行 不是我想要的那样?
- 我应该如何修改它以实现我想要的目标(多个缓慢的发布)?
我认为这是因为出版物被阻止了。
您可以使用 meteorhacks:unblock 取消阻止发布:
https://atmospherejs.com/meteorhacks/unblock
最好在每个出版物的开头使用 this.unblock()(一旦您添加了 meteorhacks:unblock)。
Meteor 按顺序处理 DDP 消息(包括订阅)。这确保您可以执行某些操作,例如删除对象然后以正确的顺序将其插入,而不是 运行 出现任何错误。
在 Meteor.methods
中支持使用 this.unblock()
来解决此问题,以允许处理下一个可用的 DDP 消息,而无需等待前一个消息完成执行。不幸的是,这不适用于 Meteor 核心中的 Meteor.publish
。您可以在此处查看有关此问题的讨论(和一些解决方法):https://github.com/meteor/meteor/issues/853
还有一个包将此功能添加到出版物中:
Why doesn't my experiment run the way I wanted it to?
Meteor._sleepForMs
阻碍了 implemented:
Meteor._sleepForMs = function (ms) {
var fiber = Fiber.current;
setTimeout(function() {
fiber.run();
}, ms);
Fiber.yield();
};
调用它可以防止下一行在 fiber 内部执行,直到持续时间结束。但是,由于 fiber 的工作方式,这不会阻止节点服务器处理其他事件(即执行另一个发布)。
这里是关于 Meteor 中纤维的讨论:https://www.youtube.com/watch?v=AWJ8LIzQMHY
How should I modify it to achieve my desired goal (multiple slow publications) ?
尝试使用 Meteor.setTimeout
异步模拟延迟。
Meteor.publish('foo', function() {
console.log('publishing foo');
var self = this;
Meteor.setTimeout(function () {
console.log('waking up foo');
self.ready();
}, 2000);
});
我想模拟多个慢速订阅。客户端同时订阅两个或多个发布,结果稍后到达。
目标是能够看到网络延迟和随机性如何影响我的应用程序(它会出错,因为我希望一个发布先于另一个发布,...)。
对发布使用以下简短设置:
// server/foo.js
Meteor.publish('foo', function() {
console.log('publishing foo');
Meteor._sleepForMs(2000);
console.log('waking up foo');
this.ready();
});
// server/bar.js is the same with a different name
Meteor.publish('bar', function() {
console.log('publishing bar');
Meteor._sleepForMs(2000);
console.log('waking up bar');
this.ready();
});
如 this amazing answer 中所见,由于 Meteor._sleepForMs
,两个出版物都变慢了。
然后客户端订阅每个发布:
Meteor.subscribe('bar'); // /client/bar.js
Meteor.subscribe('foo'); // /client/foo.js
从那里我希望首先看到两个 'publishing'
日志,然后是 'waking up'
.
然而,这出现在控制台中:
15:37:45? publishing bar
15:37:47? waking up bar
15:37:47? publishing foo
15:37:49? waking up foo
(我像那天一样去掉了一些无关紧要的绒毛)
很明显它 运行 是同步的。我认为有两件事可能导致这种情况:服务器 waitForMs
会完全阻塞服务器(相当奇怪),或者客户端订阅设计。
为了确保它不是服务器,我添加了一个简单的检测信号:
Meteor.setInterval(function() { console.log('beep'); }, 500);
而且它没有停止哔哔声,所以服务器没有完全阻塞。
因此我怀疑问题出在客户端订阅模型中,它可能会等待订阅准备就绪后再调用另一个..?
因此,两个问题:
- 为什么我的实验 运行 不是我想要的那样?
- 我应该如何修改它以实现我想要的目标(多个缓慢的发布)?
我认为这是因为出版物被阻止了。
您可以使用 meteorhacks:unblock 取消阻止发布: https://atmospherejs.com/meteorhacks/unblock
最好在每个出版物的开头使用 this.unblock()(一旦您添加了 meteorhacks:unblock)。
Meteor 按顺序处理 DDP 消息(包括订阅)。这确保您可以执行某些操作,例如删除对象然后以正确的顺序将其插入,而不是 运行 出现任何错误。
在 Meteor.methods
中支持使用 this.unblock()
来解决此问题,以允许处理下一个可用的 DDP 消息,而无需等待前一个消息完成执行。不幸的是,这不适用于 Meteor 核心中的 Meteor.publish
。您可以在此处查看有关此问题的讨论(和一些解决方法):https://github.com/meteor/meteor/issues/853
还有一个包将此功能添加到出版物中:
Why doesn't my experiment run the way I wanted it to?
Meteor._sleepForMs
阻碍了 implemented:
Meteor._sleepForMs = function (ms) {
var fiber = Fiber.current;
setTimeout(function() {
fiber.run();
}, ms);
Fiber.yield();
};
调用它可以防止下一行在 fiber 内部执行,直到持续时间结束。但是,由于 fiber 的工作方式,这不会阻止节点服务器处理其他事件(即执行另一个发布)。
这里是关于 Meteor 中纤维的讨论:https://www.youtube.com/watch?v=AWJ8LIzQMHY
How should I modify it to achieve my desired goal (multiple slow publications) ?
尝试使用 Meteor.setTimeout
异步模拟延迟。
Meteor.publish('foo', function() {
console.log('publishing foo');
var self = this;
Meteor.setTimeout(function () {
console.log('waking up foo');
self.ready();
}, 2000);
});