Skip to content
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

settimeout for mqtt socket #890

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

prabhu-yu
Copy link

@prabhu-yu prabhu-yu commented Jul 3, 2024

Problem statement:
If there are any network issues, mqtt will block on socket non-deterministically.
In such cases, only way to come out of the blocking is to reboot using watch dog timers.
This is costly solution.

Solution:
Alternatively, developer can set the max timeout for the socket.
Upon any issue, mqtt lib will throw exception. Developer can catch it, take
right actions like, restarting the task without rebooting the whole device.

This brings determinism and gives the control to developer to choose right time for her/his use case. This fix works for async applications too.

(I plan to make whole umqtt async compatible.)

def connect(self, clean_session=True):
self.sock = socket.socket()
self._sock = self.sock = socket.socket()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to instead add a timeout=None argument to this connect() method. Then call self.sock.settimeout(timeout) after creating the socket.

That would mean that the connect call below, and wrap_socket, would also apply the timeout.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dpgeorge ,
Agree with you. That will be better.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@prabhu-yu Will you update this PR with the above suggestion? If not I can do it.

Copy link
Author

@prabhu-yu prabhu-yu Nov 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dpgeorge,
Thanks for reminding me.
Here is the change and test.
Please let me know your comments.

Test:
I set the some timeout=3
mqtt_client.connect(clean_session=True, timeout=3)
and begin publishing with below call.
mqtt_client.publish(b'dev/1/ota/ota_server_tx', msg, qos=1)
(I used MQTTX to monitor msgs)
After sometime, to cause n/w failure, I physically removed n/w cable of my PC.
I observed that OSError exception thrown exactly after the 3 seconds.
However, pl note: qos=0 in publish() does not have any effect due to this change. This is expected, I think. ie, if one wants exception upon n/w failure, he or should use qos=1.
I repeated tests with qos=1 for different timeout.

⟶ micropython test.py
client_id=555555555,
broker=<somebroker.emqxsl.com>
connection ok
publishing 1 msg per second
publishing 1 msg per second
publishing 1 msg per second
publishing 1 msg per second
publishing 1 msg per second
got OSError exception during publish!

@dpgeorge
Copy link
Member

I plan to make whole umqtt async compatible.

See https://github.com/tve/mqboard/tree/master/mqtt_async

@prabhu-yu
Copy link
Author

I plan to make whole umqtt async compatible.

See https://github.com/tve/mqboard/tree/master/mqtt_async

Thank you for the link.
Is it going to be part of the micropython? [https://github.com/micropython/micropython-lib/tree/master/micropython]
If so, it will have higher visibility.

@dpgeorge
Copy link
Member

Thank you for the link.
Is it going to be part of the micropython?

Actually, this is a better version: https://github.com/peterhinch/micropython-mqtt

Eventually we would like to add links from this repository to external/third-party libraries like the above, to make them easier to install, and have better visibility.

@prabhu-yu
Copy link
Author

prabhu-yu commented Nov 1, 2024

I plan to make whole umqtt async compatible.

See https://github.com/tve/mqboard/tree/master/mqtt_async

This will be a lot helpful to all those who use async. Async really shines as it gives better control to developer over threads/processes in terms of scheduling. This in turn solves many locking issues that are common in threads. in anycase, async mqtt blends nicely into all async applications.

self.sock = socket.socket()
if timeout is not None:
self.sock.settimeout(timeout)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you pass None to settimeout then it sets it to blocking mode, which is also the default after creating a fresh socket.

So, the if timeout is not None line is not needed. It can just set the timeout unconditionally and still have the same behaviour as before. Doing it that way makes the code smaller and simpler.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dpgeorge ,
Agree with you. I submitted the change.
(I was trying to be little cautious by avoiding to execute settimeout when default value arrives! I agree, this is not a clean solution!)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dpgeorge
May you please suggest the next step?
Should I create a PR for this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change looks good now, thank you.

But I see on your commits that the author is Your Name <you@example.com>. Is that intentional? Usually we require a proper name and email, for attribution of the work.

If you want to remain anonymous, I can change the author to my name.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dpgeorge ,
Thank you for notifying me 🙏.
I have updated my Name/E-mail id and pushed it again.
Please let me know if I need to do something further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants