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

Reconnection / retry error with Paho MQTT 1.2 leads to ever increasing thread usage #2471

Closed
michael-simons opened this issue Jun 6, 2018 · 9 comments · Fixed by #2472
Closed

Comments

@michael-simons
Copy link

As a follow up to my tweet.

Find attached a simple Spring Integration MQTT application (mqtt-paho-client-threading-bug.zip). It's a Spring Boot app, just run

./mvnw clean spring-boot:run

You'll find the app trying to reach a MQTT broker on tcp://localhost:45678 (I chose this port to make sure there is no broker answering).

The app will fail, print the MQTT Paho exception and continue.

I'll added a scheduled task that prints the number of live threads. As you see they'll increse by 2 threads after each failed connection retry.

This happens during startup as well as during runtime, for example if the broker goes away in between.

A downgrade to Paho 1.1.1 as suggested in eclipse-paho/paho.mqtt.java#402 respectivly SebaDro/SOS@8b9f09e helps, for example like this:

    <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-mqtt</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.eclipse.paho</groupId>
                    <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.eclipse.paho</groupId>
            <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
            <version>1.1.1</version>
            <scope>compile</scope>
        </dependency>

With Paho 1.1.1 the number of threads stays constant.

@hbergmey
Copy link

hbergmey commented Jun 6, 2018

Unfortunately I cannot go back to 1.1.1 as then my client connections become unstable. As a matter of fact, I do not receive any further messages after the initial topic report. Paho 1.2.0 fixed this strange behavior.

Somehow we need to fix the thread shutdown issue.

@garyrussell
Copy link
Contributor

They really need to fix the client; we can look at closing/creating a new client each time, but that just seems wrong.

@hbergmey
Copy link

hbergmey commented Jun 6, 2018

Looking into the Paho Code, I see that the MqttAsyncClient can be setup to use an explicitly given ThreadPool like so:

new MqttAsyncClient(url, clientId, persistence, new TimerPingSender(), Executors.newScheduledThreadPool(10))

Do you see a chance to explicitly kill this threadpool on app/container shutdown?

Neither @PreDestroy nor finalize() cause my close() function with mqttClient.disconnectForcibly() to be called.

@garyrussell
Copy link
Contributor

My mistake; it's our bug; we do create a new client on each attempt; we just don't clean up the old one.

@hbergmey
Copy link

hbergmey commented Jun 6, 2018

I join the "mea culpa" chant: My mistake was the @PreDestroy annotation at the wrong class. Obviously it only works in a Spring service.

I am now calling the following in a @PreDestroy hook

@PreDestroy
public void close() {
   IMqttToken disconnectToken = mqttClient.disconnect();
   disconnectToken.waitForCompletion(10000);
   mqttClient.close(true);
   mqttClient = null;
}

garyrussell added a commit to garyrussell/spring-integration that referenced this issue Jun 6, 2018
Fixes spring-projects#2471

Call `close()` on the client whenever the connection is lost or can't be
established, to release resources in the client.

**cherry-pick to 5.0.x, 4.3.x**
@garyrussell
Copy link
Contributor

I tested your app against the snapshot locally and there is no more leak.

Releases that will include this fix are scheduled for next Wednesday.

@michael-simons
Copy link
Author

Wow, awesome reaction. Thanks a lot!

artembilan pushed a commit that referenced this issue Jun 6, 2018
Fixes #2471

Call `close()` on the client whenever the connection is lost or can't be
established, to release resources in the client.

**cherry-pick to 5.0.x, 4.3.x**
artembilan pushed a commit that referenced this issue Jun 6, 2018
Fixes #2471

Call `close()` on the client whenever the connection is lost or can't be
established, to release resources in the client.

**cherry-pick to 5.0.x, 4.3.x**

(cherry picked from commit f9cea64)
artembilan pushed a commit that referenced this issue Jun 6, 2018
Fixes #2471

Call `close()` on the client whenever the connection is lost or can't be
established, to release resources in the client.

**cherry-pick to 5.0.x, 4.3.x**

(cherry picked from commit f9cea64)

# Conflicts:
#	spring-integration-mqtt/src/test/java/org/springframework/integration/mqtt/MqttAdapterTests.java
@garyrussell
Copy link
Contributor

Need similar logic in the outbound adapter.

@jmax01
Copy link

jmax01 commented Oct 10, 2018

Thank you and for reference, the details of what we experienced: https://gitter.im/spring-projects/spring-integration?at=5bbd2483bbdc0b250512e7ce

Need similar logic in the outbound adapter.

artembilan pushed a commit that referenced this issue Oct 10, 2018
artembilan pushed a commit that referenced this issue Oct 10, 2018
artembilan pushed a commit that referenced this issue Oct 10, 2018
Resolves #2471

# Conflicts:
#	spring-integration-mqtt/src/test/java/org/springframework/integration/mqtt/MqttAdapterTests.java
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 a pull request may close this issue.

4 participants