-
Notifications
You must be signed in to change notification settings - Fork 815
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature disconnects #744
Feature disconnects #744
Conversation
@andsel may I ask you to take a look at this please? Or to assign this request to someone who may address this? Small note in regards to CONNECT+PUBLISH issue: the root cause is that the implementation mainly relies on NettyUtils.clientID(channel) call, that requires channel to be associated with the connection. At the moment of CONNECT the new association creation is implemented by firing out the Thank you. |
Hi @source-c
|
Thank you, @andsel. Both PRs were modified in accordance to your comments. |
Thanks @source-c I'll review in the next days, thank you for contributing to the project. I'll comment on them, if I have any doubts. |
Co-authored-by: Andrea Selva <selva.andre@gmail.com>
Hi there! @andsel, I see ubuntu-18.04 have were all failed with no run, twice. Is there a chance for this commit to be merged to the |
Hi @source-c yes it's possible, but I have to review it and had no time in the past weeks :-( I'll try to do it during next weekend |
Oh, fine then. Thank you! |
Hi @source-c I tried to reproduce with following (run it with jbang), but haven't luck to reproduce your issue. ///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5
package io.moquette.testembedded;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttClientPersistence;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
public class TestClient {
public static void main(String[] args) throws MqttException {
MqttClientPersistence dataStore = new MemoryPersistence();
MqttClient client = new MqttClient("tcp://localhost:1883", "TestClient", dataStore);
client.connect();
client.publish("/temperature", new byte[] {0x14}, 0, false);
client.disconnect();
client.close();
}
} Please, could you expand your explanation of the problem? |
Seems, you cannot reproduce that because of implementation differences: org.eclipse.paho.client.mqttv3.MqttClient:
when paho.mqtt.client does just:
you see there is no await at pythonic client (which is used very broadly).
both
and this channel in turn is yet not completely initialized. |
I've tried also with Java Paho Async client and HiveMQ async, but neither of the two exposes such behavior.
although it describes this non normative comment:
So it seems that if the broker receives the PUB before sending the CONN_ACK, and the connection is accepted, then it has to process the PUB as if it's a valid. I think that to implement such behavior we should move the assignment of
In this case:
|
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.
Left a request to change the layout of the code, plus I would ask to cover this with a unit test that verifies the behaviors:
- dropping a connection for a non existing session.
- dropping a connection for an existing session.
However it's not clear to me why SessionRegistry.closeSession is not enough for your use case.
BTW in the suggestion i removed
client.cleanUp();
pool.remove(clientId);
because are implicit in the call to purgeSessionState
Co-authored-by: Andrea Selva <selva.andre@gmail.com>
Of course, implementing that in such a way follows the spec more precisely. But it doesn't neglect that empty clientId case should be either be covered at the routing. At least to identify a case of collision/race if any. Also, I suppose changing that behaviour is to be done separately to avoid mess, does it? |
There are a lot use cases when forcing disconnect is used under hard pressure and in accordance to security policies. Some of use cases already discussed at #747 BTW. |
Yes, it's better separate in another PR |
I understand, but it's not clear to me if the intended effect of the new method should be like a standard close; which shutdown the MQTTConnection and clean the Session status (means topic subscriptions and queues) if needed (clean session = false). |
Unfortunatelly, second case is most prefered. We should remove all the session internals disregading its state. The state might be not clean, the channel might not be operational, server (broker) might be overwhelmed by unwanted (sometimes broken) requests. Forcing session drop (i.e. kicking off the client) we perserve server stability among other reasons, trying to keep it operational for all other clients. |
However you are right - this should be decided by end user, so I remade cleanup contract and now session cleanup is to be specified by outer parameter explicitly. |
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.
HI @source-c , I'm not a big fan of boolean flag parameter to customize the behavior of a method, I prefer to create 2 different methods that better express the intention.
On public API I avoid the feature flag, on internal if it generates more work and code duplication I could accept.
We are almost ready to go, please write a unit test to cover introduced functionality or let me know if you want I wrote it :-) adding some commits to this PR.
Co-authored-by: Andrea Selva <selva.andre@gmail.com>
Co-authored-by: Andrea Selva <selva.andre@gmail.com>
May I ask you to do it yourself please? It seems like we have quite different styling views, so I have no doubts your implementations will be much more clear than mine. :) |
Also fixed an issue of race that caused exception on connect, that is very easy to reproduce:
that causes:
The disconnection feature works like this (traces):
We maintain a clojure library that wraps moquette, so the tests are written in clojure (actually this functionality is at trunk now and awaits for upstream updates), however they are way simple, so you may take a look by yourself - https://github.com/dkdhub/clj-mqtt-broker/blob/3d59a2244afec43ae2a3522ac9173ae683a9dc3d/test/basic.clj#L129
Looking forward to hearing from you!