mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Use an object instead of an array to store connection callbacks. This way we can ensure a callback is never called after its stop handle is called.
This commit is contained in:
@@ -995,9 +995,12 @@ _.extend(Subscription.prototype, {
|
||||
Server = function () {
|
||||
var self = this;
|
||||
|
||||
// List of callbacks to call when a new connection comes in to the
|
||||
// server and completes DDP version negotiation.
|
||||
self.connectionCallbacks = [];
|
||||
// Map of callbacks to call when a new connection comes in to the
|
||||
// server and completes DDP version negotiation. Use an object instead
|
||||
// of an array so we can safely remove one from the list while
|
||||
// iterating over it.
|
||||
self.connectionCallbacks = {};
|
||||
self.nextConnectionCallbackId = 0;
|
||||
|
||||
self.publish_handlers = {};
|
||||
self.universal_publish_handlers = [];
|
||||
@@ -1073,11 +1076,12 @@ _.extend(Server.prototype, {
|
||||
|
||||
fn = Meteor.bindEnvironment(fn, "onConnection callback");
|
||||
|
||||
self.connectionCallbacks.push(fn);
|
||||
var id = self.nextConnectionCallbackId++;
|
||||
self.connectionCallbacks[id] = fn;
|
||||
|
||||
return {
|
||||
stop: function () {
|
||||
self.connectionCallbacks = _.without(self.connectionCallbacks, fn);
|
||||
delete self.connectionCallbacks[id];
|
||||
}
|
||||
};
|
||||
},
|
||||
@@ -1092,9 +1096,11 @@ _.extend(Server.prototype, {
|
||||
// Creating a new session
|
||||
socket._meteorSession = new Session(self, version, socket);
|
||||
self.sessions[socket._meteorSession.id] = socket._meteorSession;
|
||||
_.each(self.connectionCallbacks, function (callback) {
|
||||
if (socket._meteorSession)
|
||||
_.each(_.keys(self.connectionCallbacks), function (id) {
|
||||
if (_.has(self.connectionCallbacks, id) && socket._meteorSession) {
|
||||
var callback = self.connectionCallbacks[id];
|
||||
callback(socket._meteorSession.connectionHandle);
|
||||
}
|
||||
});
|
||||
} else if (!msg.version) {
|
||||
// connect message without a version. This means an old (pre-pre1)
|
||||
|
||||
@@ -52,6 +52,38 @@ Tinytest.addAsync(
|
||||
);
|
||||
|
||||
|
||||
testAsyncMulti(
|
||||
"livedata server - onConnection doesn't get callback after stop.",
|
||||
[function (test, expect) {
|
||||
var afterStop = false;
|
||||
var expectStop1 = expect();
|
||||
var stopHandle1 = Meteor.onConnection(function (conn) {
|
||||
stopHandle2.stop();
|
||||
stopHandle1.stop();
|
||||
afterStop = true;
|
||||
// yield to the event loop for a moment to see that no other calls
|
||||
// to listener2 are called.
|
||||
Meteor.setTimeout(expectStop1, 10);
|
||||
});
|
||||
var stopHandle2 = Meteor.onConnection(function (conn) {
|
||||
test.isFalse(afterStop);
|
||||
});
|
||||
|
||||
// trigger a connection
|
||||
var expectConnection = expect();
|
||||
makeTestConnection(
|
||||
test,
|
||||
function (clientConn, serverConn) {
|
||||
// Close the connection from the client.
|
||||
clientConn.disconnect();
|
||||
expectConnection();
|
||||
},
|
||||
expectConnection
|
||||
);
|
||||
}]
|
||||
);
|
||||
|
||||
|
||||
Meteor.methods({
|
||||
livedata_server_test_inner: function () {
|
||||
return this.connection.id;
|
||||
|
||||
Reference in New Issue
Block a user