2

I'm working on an issue related to Okhttp connection leaks. The leak stack trace seems to pointing to this WebSocket connection being opened in PodOperationsImpl#L267:

        try {
            URL url = new URL(URLUtils.join(getResourceUrl().toString(), sb.toString()));
            Request.Builder r = new Request.Builder().url(url).header("Sec-WebSocket-Protocol", "v4.channel.k8s.io").get();
            OkHttpClient clone = client.newBuilder().readTimeout(0, TimeUnit.MILLISECONDS).build();
            final ExecWebSocketListener execWebSocketListener = new ExecWebSocketListener(getConfig(), in, out, err, errChannel, inPipe, outPipe, errPipe, errChannelPipe, execListener);
            clone.newWebSocket(r.build(), execWebSocketListener);
            execWebSocketListener.waitUntilReady();
            return execWebSocketListener;
        } catch (Throwable t) {
            throw KubernetesClientException.launderThrowable(forOperationType("exec"), t);
        }

When I run the test provided in the issue itself, I see connection leak messages on logs:

WARNING: A connection to http://localhost:48271/ was leaked. Did you forget to close a response body?
java.lang.Throwable: response.body().close()

But when I create OkHttpClient from a new instance instead of cloning it from the previous one, these connection leak warnings are reduced by 3/4th. Is cloning client prone to connection leaks? Or whether I'm not doing it the right way? Is there any way to ensure if we can handle these connection leak warning messages?

One more thing, the websocket is opened using ExecWebSocketListener, which already implements AutoCloseable. Although doing try-with-resources from caller does seem to avoid these warnings. But I'm not sure whether it's actually fixing the root cause of leaks.

Rohan Kumar
  • 5,427
  • 8
  • 25
  • 40

1 Answers1

0

The clone is unrelated. This warning relies on the garbage collector to find instances that went out of scope before they were closed, and this process is neither immediate nor particularly reliable.

Jesse Wilson
  • 39,078
  • 8
  • 121
  • 128
  • Hi, Sorry for the delayed response. We're trying to get rid of these leak warnings from our codebase. Where exactly we are supposed to do `response.close()` in case of WebSocket operations? I don't see any in the [example](https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/WebSocketEcho.java) provided in okhttp repo. – Rohan Kumar Sep 07 '18 at 09:10
  • We were suspicious about cloned client but if we drop cloned client we can and will have read timeouts on WebSocket operations – Rohan Kumar Sep 07 '18 at 09:12
  • I'm trying to close response body here and there in onOpen and in onFailure but I always get leak. [This](https://github.com/fabric8io/kubernetes-client/blob/master/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/PodOperationsImpl.java#L267) is the place from which leaks are happening, and [here](https://github.com/fabric8io/kubernetes-client/blob/7ea9ce885f9fad72949db6e3f5cc8dceb8ce8766/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/ExecWebSocketListener.java#L223-L236) is the listener . Would really appreciate if you could take a look. – Rohan Kumar Sep 07 '18 at 09:12