-
-
Notifications
You must be signed in to change notification settings - Fork 506
Conversation
setTimeout(function () | ||
{ | ||
client1.disconnect(); | ||
}, 500); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setTimeout
is bad and should be avoided in tests.
Do this instead:
- use QoS 1
- count the numer of
"publish"
events. - call
disconnect()
on"puback"
, after verifying the number of events.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There will be one publish event. How do you know unexpected duplicates won't be received if you disconnect straight away?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you use QoS 1, PUBLISH packets will be sent to all subscribers before sending out a PUBACK to the sender. So, if QoS 1 is implemented correctly, all the duplicates will arrive before the PUBACK. If not, we have one more bug.
the Using a per-server message counter might be easier and safe. Example algorithm:
Ideally the counter should be cyclic at |
mosca.trail[uid] will be deleted when the message is deleted. Does mosca keep the message in memory forever? In the |
Nope, you are right, sorry. I thought that would be global, as the options are not passed through all the ascoltatori backends. If it's bound to the message, then multiple Mosca sharing the same 'parent' broker will have the same problem.
Nope, the counter is incremented only when a message enter the current Mosca instance (in the first |
Can't modify topic - can't set property on primitives: > wup = "foo"
'foo'
> wup._foo = 90
90
> wup
'foo'
> wup._foo
undefined |
The other thing I thought is it means each ascoltatore has to call all callbacks registered for a topic before it handles any other messages. |
Ok, then we need to ensure that in Ascoltatori the options object is always present, even if it's empty, and add the |
|
Would you like to add that to the PR? |
Sure. Mosca or Ascoltatori do you think? |
Think Ascoltatori is tidiest. Adding |
Yes. Let ensure there is always an 'option' obj for each message delivered. Il giorno sabato 19 ottobre 2013, David Halls ha scritto:
|
Actually, |
So that works but what if the same |
…ing a message to prevent same message being sent twice to a connection. Assumes: - options is always an object and never null - fresh options object is minted for each message
OK so I pushed what I have. I tested ascoltatori against it. |
I still need to fix the test |
Weird - travis build worked on 0.10 but not on 0.8 |
Hmm, repro'd failure on 0.8. Strange... |
very weird. I don't exactly now what's going on.. only that supporting 0.8 is really hard. |
The MQTTConnection gets and emits |
Interesting- added a log to readable-stream.Writable.emit (intercepted it) and for that test, it thinks the registered function for function (packet) {
that.setUpTimer();
packet.topic = rewriteTopic(packet.topic);
that.server.authorizePublish(that, packet.topic, packet.payload, function(err, success) {
that.handleAuthorizePublish(err, success, packet);
});
} |
I don't really understand that - from the code, it looks like the tests are using a |
I think the problem is on node 0.8, mqtt uses readable-stream which is flushing (or rather, not) differently. We don't wait for the stream to flush (neither does mqtt). I don't think we need to alter the code of mosca (or mqtt) since we don't actually care that it's gone. However, the test gets puback straight away and so then disconnects. (The data hasn't yet been flushed). |
A |
mqtt uses readable-stream which doesn't send data straight away. So wait before disconnecting so the data gets chance to go.
OK, build now passes. |
@@ -168,6 +169,13 @@ Client.prototype.actualSend = function(packet, retry) { | |||
Client.prototype._buildForward = function() { | |||
var that = this; | |||
this.forward = function(topic, payload, options, subTopic, initialQoS, cb) { | |||
if (options._dedupId === undefined) { | |||
options._dedupId = that.server.nextDedupId(); | |||
} else if (options._dedupId === that._lastDedupId) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a <=, not a ===.
@mcollina please review. I couldn't really think of an alternative to |
Ah just missed your review, fixing... |
It's a right assumption. The callback is not deferred, otherwise the performance will just grow too much. @davedoesdev regarding the puback, I got the problem. How about using two clients? One for publishing and one for subscribing? That should remove the |
:( It does use two clients. Client 1 subscribes, client 2 publishes. The problem is that var called = 0;
client1.on("publish", function(packet) {
expect(packet.topic).to.equal("a/b");
expect(packet.payload).to.equal("some other data");
if (!packet.dup) {
expect(called).to.equal(0);
called++;
}
});
client1.on("suback", function() {
buildAndConnect(d, function(client2) {
client2.on("puback", function() {
setTimeout(function () {
expect(called).to.equal(1);
client1.disconnect();
client2.disconnect();
}, 1000);
});
client2.publish({
topic: "a/b",
payload: "some other data",
messageId: messageId,
qos: 1
});
});
});
client1.subscribe({
subscriptions: subscriptions,
messageId: messageId
}); |
I'm taking it from now and see if I can remove the damn |
Thanks. I ended up in the |
I guess one way would be to get client1 to send a message back once it's received it. However, this wouldn't give time for any duplicates to be registered. |
Ok, merged, it's fixed now, without a |
Thank again! This was very important (and long to debug). |
Yes, that works. |
I verified it fixes MQTTAscoltatori too - will send that pull request once this one is merged.
Closes #62.