Skip to content

Blocking loop() function and issues with PINGREQ and timeout=0 #86

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

Closed
ajlennon opened this issue Aug 7, 2021 · 1 comment
Closed

Blocking loop() function and issues with PINGREQ and timeout=0 #86

ajlennon opened this issue Aug 7, 2021 · 1 comment

Comments

@ajlennon
Copy link
Contributor

ajlennon commented Aug 7, 2021

Hi all,

Thanks for this - am trying to integrate it into some code and having some problems.

One is that I think a reasonable use-case is to call poll() repeatedly in my main loop.

The poll() code documentation states it is non-blocking (as the PAHO call is for example) but it actually blocks for 1s which is not trivial for an embedded system main loop. I suggest timeout should default to 0.

That said, if I set timeout to zero there is a problem as the poll() call will be called multiple times while a ping request is outstanding and this results in multiple ping requests being made. I see 3-5 at a time with DEBUG logging on.

This is because self._timestamp is being reset after self.ping()

The solution seems to be pretty straightforward which is to reset self._timestamp() before sending the ping()

e.g.

def loop(self, timeout=1):
        """Non-blocking message loop. Use this method to
        check incoming subscription messages.
        Returns response codes of any messages received.
        :param int timeout: Socket timeout, in seconds.
        """
        if self._timestamp == 0:
            self._timestamp = time.monotonic()
        current_time = time.monotonic()
        if current_time - self._timestamp >= self.keep_alive:
            self._timestamp = 0
            # Handle KeepAlive by expecting a PINGREQ/PINGRESP from the server
            if self.logger is not None:
                self.logger.debug(
                    "KeepAlive period elapsed - requesting a PINGRESP from the server..."
                )
            rcs = self.ping()
            return rcs
        self._sock.settimeout(timeout)
        rc = self._wait_for_msg()
        return [rc] if rc else None
ajlennon added a commit to DynamicDevices/Adafruit_CircuitPython_MiniMQTT that referenced this issue Aug 7, 2021
If I set timeout to zero there is a problem as the poll() call will be
called multiple times while a ping request is outstanding and this
results in multiple ping requests being made. I see 3-5 at a time with
DEBUG logging on.

This is because self._timestamp is being reset after self.ping()

The solution seems to be pretty straightforward which is to reset
self._timestamp() before sending the ping()

Signed-off-by: Alex J Lennon <[email protected]>
brentru added a commit that referenced this issue Aug 9, 2021
adafruit_minimqtt: Fix issue #86 with multiple poll() PINGREQs
@brentru
Copy link
Member

brentru commented Aug 11, 2021

Fixed in #87, closing...

@brentru brentru closed this as completed Aug 11, 2021
rtwfroody pushed a commit to rtwfroody/Adafruit_CircuitPython_MiniMQTT that referenced this issue Sep 18, 2022
If I set timeout to zero there is a problem as the poll() call will be
called multiple times while a ping request is outstanding and this
results in multiple ping requests being made. I see 3-5 at a time with
DEBUG logging on.

This is because self._timestamp is being reset after self.ping()

The solution seems to be pretty straightforward which is to reset
self._timestamp() before sending the ping()

Signed-off-by: Alex J Lennon <[email protected]>
rtwfroody pushed a commit to rtwfroody/Adafruit_CircuitPython_MiniMQTT that referenced this issue Sep 18, 2022
…ingreqs

adafruit_minimqtt: Fix issue adafruit#86 with multiple poll() PINGREQs
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