gausby / tortoise

A MQTT Client written in Elixir
Apache License 2.0
312 stars 54 forks source link

Logger handler does not handle connection :terminated #97

Open brianmay opened 5 years ago

brianmay commented 5 years ago

I see the logger class handles :terminating but not :terminated.

https://github.com/gausby/tortoise/blob/master/lib/tortoise/handler/logger.ex#L26

Actually might help if these states were documented better. The example in README.md only lists :up and :down as valid options. Presumably :terminating happens first, followed by :terminated, followed by :down? Not really sure.

I noticed my code generating the following error, which is why I chose to investigate:

** (FunctionClauseError) no function clause matching in Robotica.Client.connection/2 
    (robotica) lib/robotica/client.ex:16: Robotica.Client.connection(:terminated, %Robotica.Client.State{})

Regards

brianmay commented 5 years ago

Actually just noticed a "terminate" function, but maybe this isn't used now??? I am confused.

https://github.com/gausby/tortoise/blob/113e70b43d0d6a5eb347bc761ac0d82c95ede756/lib/tortoise/handler/logger.ex#L56

gausby commented 5 years ago

Internally tortoise have a pubsub like mechanism for informing its various processes of events happening in the system. One of the topics is the connection topic, and one of the messages it can receive is :terminating. The "terminating" event is used when a process request a network port it can use to put data on when it want to publish a package to the broker—in the case it receive a :terminating message it will not await the port and instead inform the requester that the message could not be transmitted because the client is terminating.

So, the connection callback can receive a "terminating" message. It should happen before you get the :down message when the client is terminated by an administrator.

The terminate/2-callback mimic the OTP behaviour and is the opposite of the init/1 callback. You can use the terminate callback to close down some support system that you created in the init—also, should the process crash the reason would be the error tuple.

Notice that I am working on upgrading the client to MQTT 5. This will bring some changes to the design. I hope that I can make a compatibility mode so the code that currently rely on tortoise should work (or work with minimal changes). The changes are due to major changes in the protocol itself, which would make the current Tortoise design a bit too opinionated—MQTT 3.1.1 was a more strict protocol, where MQTT 5 is more open and "do what ever you want"; so I need to expose more of the MQTT internals to the end user to support this :)

brianmay commented 5 years ago

Thanks for these details. Where does the connection :terminated message fit into this?

gausby commented 5 years ago

There is a difference between being "down" (we might come up again later) and "terminated" (the connection is closed and will not come up again).

But these semantics might change in the future, because I had to rewrite the connection logic to accommodate the extended authentication exchange introduced in MQTT 5.

brianmay commented 5 years ago

Ok, so looks like in current versions I should look for both :terminated and :down if I want to know when the connection is down?