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

loop_forever() timeout #543

Closed
le0pa-RD opened this issue Dec 27, 2020 · 5 comments
Closed

loop_forever() timeout #543

le0pa-RD opened this issue Dec 27, 2020 · 5 comments

Comments

@le0pa-RD
Copy link

le0pa-RD commented Dec 27, 2020

Hello, I've been using this library to send and receive some data between an Arduino and a Raspberry Pi.
In the raspberry program, I connect to my Arduino and I read the messages containing the data I was searching for.
However, the Arduino sends data only one time while the receiving program runs in a loop.
I tried to set the loop_forever function with a timeout "client.loop_forever(60000, 1)" but when it times out it connects again to the client. Is there any way I can quit the program when loop_forever times out?

@lucacillario
Copy link
Contributor

I'm not sure I understand your question. In any case i think that you have misunderstood the meaning of the timeout parameter. client.loop_forever(timeout=60000) does not mean "run the loop for 60000 seconds and after that break and quit the program". timeout refers to how long the thread must block on the socket waiting for new messages to be processed (incoming and / or outgoing). At the end of that timeout interval, if there are no new messages to process, the thread continues with its execution and will try again later.

If you want to stop the execution of your program after 60000 seconds, you could do this:

import time

client= mqtt.Client()
client.connect(broker,port)
client.loop_start()

# do stuff ...

time.sleep(60000)
client.disconnect()
client.loop_stop()

This is a very simplified solution, but if you explain better what you need to do I will gladly try to help you 😄 .

@le0pa-RD
Copy link
Author

le0pa-RD commented Jan 9, 2021

What I wanted to do is to set a timeout from the last message received, if no more messages are incoming and the timeout ends it quits the program.
If I understood what you did above your program just waits 60000 seconds from the loop start and then quits, right?

Thanks for the help :)

@lucacillario
Copy link
Contributor

Yes, that's right.

So, if you need to quit the program after a certain period of not receiving any messages, you might try something like this:

from paho.mqtt.client import Client
import time


client = Client()
client.connect(broker, port)
client.loop_start()

run = True
TIMEOUT = 10  # seconds
while run:
	client._msgtime_mutex.acquire()
	last_msg_in = client._last_msg_in
	client._msgtime_mutex.release()
	now = time.monotonic()
	if now - last_msg_in > TIMEOUT:
	    client.disconnect()
	    client.loop_stop()
	    run = False
	else:
	    time.sleep(1)

In the example above I am accessing some private variables, and this is not great (but it's just an example). You could implement a timer that does the same thing, without having to access private variables. Keep in mind that with loop_start you end up in multithreaded environment, so even a simple timer needs to be handled with care.

Another way to solve your problem is to use a "special" message which, once received by the client, triggers the disconnection.

@le0pa-RD
Copy link
Author

le0pa-RD commented Jan 9, 2021

Thanks for the help

@le0pa-RD le0pa-RD closed this as completed Jan 9, 2021
@lucacillario
Copy link
Contributor

In any case I agree with you that the semantics of the timeout parameter, in the loop_forever function, is misleading. I'm not sure if that is bug or not. I'll try to investigate.

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

No branches or pull requests

2 participants