Skip to content

Commit a388a2d

Browse files
authored
Fix netty leak (#3127)
1 parent 7771cea commit a388a2d

File tree

2 files changed

+64
-45
lines changed

2 files changed

+64
-45
lines changed

agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/profiler/service/ServiceProfilerClient.java

Lines changed: 60 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,25 @@ public ServiceProfilerClient(URL hostUrl, String instrumentationKey, HttpPipelin
6464
public Mono<BlobAccessPass> getUploadAccess(UUID profileId, String extension) {
6565
URL requestUrl = uploadRequestUri(profileId, extension);
6666

67-
return executePostWithRedirect(requestUrl)
68-
.map(
69-
response -> {
70-
if (response.getStatusCode() >= 300) {
71-
throw new HttpResponseException(response);
72-
}
73-
String location = response.getHeaderValue("Location");
74-
if (location == null || location.isEmpty()) {
75-
throw new AssertionError("response did not have a location");
76-
}
77-
return new BlobAccessPass(null, location, null);
78-
});
67+
return executePostWithRedirect(requestUrl).map(ServiceProfilerClient::getUploadAccess);
68+
}
69+
70+
private static BlobAccessPass getUploadAccess(HttpResponse response) {
71+
try {
72+
if (response.getStatusCode() >= 300) {
73+
throw new HttpResponseException(response);
74+
}
75+
String location = response.getHeaderValue("Location");
76+
if (location == null || location.isEmpty()) {
77+
throw new AssertionError("response did not have a location");
78+
}
79+
return new BlobAccessPass(null, location, null);
80+
} finally {
81+
// need to consume the body or close the response, otherwise get netty ByteBuf leak warnings:
82+
// io.netty.util.ResourceLeakDetector - LEAK: ByteBuf.release() was not called before
83+
// it's garbage-collected (see https://github.com/Azure/azure-sdk-for-java/issues/10467)
84+
response.close();
85+
}
7986
}
8087

8188
public Mono<HttpResponse> executePostWithRedirect(URL requestUrl) {
@@ -94,21 +101,7 @@ public Mono<ArtifactAcceptedResponse> reportUploadFinish(
94101
URL requestUrl = uploadFinishedRequestUrl(profileId, extension, etag);
95102

96103
return executePostWithRedirect(requestUrl)
97-
.flatMap(
98-
response -> {
99-
if (response == null) {
100-
// this shouldn't happen, the mono should complete with a response or a failure
101-
return Mono.error(new AssertionError("http response mono returned empty"));
102-
}
103-
104-
int statusCode = response.getStatusCode();
105-
if (statusCode != 201 && statusCode != 202) {
106-
logger.error("Trace upload failed: {}", statusCode);
107-
return Mono.error(new AssertionError("http request failed"));
108-
}
109-
110-
return response.getBodyAsString();
111-
})
104+
.flatMap(ServiceProfilerClient::reportUploadFinish)
112105
.flatMap(
113106
json -> {
114107
if (json == null) {
@@ -128,33 +121,55 @@ public Mono<ArtifactAcceptedResponse> reportUploadFinish(
128121
});
129122
}
130123

124+
private static Mono<String> reportUploadFinish(HttpResponse response) {
125+
if (response == null) {
126+
// this shouldn't happen, the mono should complete with a response or a failure
127+
return Mono.error(new AssertionError("http response mono returned empty"));
128+
}
129+
try {
130+
int statusCode = response.getStatusCode();
131+
if (statusCode != 201 && statusCode != 202) {
132+
logger.error("Trace upload failed: {}", statusCode);
133+
return Mono.error(new AssertionError("http request failed"));
134+
}
135+
return response.getBodyAsString();
136+
} finally {
137+
// need to consume the body or close the response, otherwise get netty ByteBuf leak warnings:
138+
// io.netty.util.ResourceLeakDetector - LEAK: ByteBuf.release() was not called before
139+
// it's garbage-collected (see https://github.com/Azure/azure-sdk-for-java/issues/10467)
140+
response.close();
141+
}
142+
}
143+
131144
/** Obtain current settings that have been configured within the UI. */
132145
public Mono<ProfilerConfiguration> getSettings(Date oldTimeStamp) {
133146

134147
URL requestUrl = getSettingsPath(oldTimeStamp);
135148

136149
HttpRequest request = new HttpRequest(HttpMethod.GET, requestUrl);
137150

138-
return httpPipeline
139-
.send(request)
151+
return httpPipeline.send(request).flatMap(response -> handle(response, requestUrl));
152+
}
153+
154+
private static Mono<ProfilerConfiguration> handle(HttpResponse response, URL requestUrl) {
155+
if (response.getStatusCode() >= 300) {
156+
// need to consume the body or close the response, otherwise get netty ByteBuf leak warnings:
157+
// io.netty.util.ResourceLeakDetector - LEAK: ByteBuf.release() was not called before
158+
// it's garbage-collected (see https://github.com/Azure/azure-sdk-for-java/issues/10467)
159+
response.close();
160+
return Mono.error(
161+
new HttpResponseException(
162+
"Received error code " + response.getStatusCode() + " from " + requestUrl, response));
163+
}
164+
return response
165+
.getBodyAsString()
140166
.flatMap(
141-
response -> {
142-
if (response.getStatusCode() >= 300) {
143-
return Mono.error(
144-
new HttpResponseException(
145-
"Received error code " + response.getStatusCode() + " from " + requestUrl,
146-
response));
167+
body -> {
168+
try {
169+
return Mono.just(mapper.readValue(body, ProfilerConfiguration.class));
170+
} catch (IOException e) {
171+
return Mono.error(e);
147172
}
148-
return response
149-
.getBodyAsString()
150-
.flatMap(
151-
body -> {
152-
try {
153-
return Mono.just(mapper.readValue(body, ProfilerConfiguration.class));
154-
} catch (IOException e) {
155-
return Mono.error(e);
156-
}
157-
});
158173
});
159174
}
160175

agent/azure-monitor-exporter/src/main/java/com/azure/monitor/opentelemetry/exporter/implementation/quickpulse/QuickPulsePingSender.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ t, getQuickPulseEndpoint(), friendlyExceptionThrown, logger)) {
125125
}
126126
} finally {
127127
if (response != null) {
128+
// need to consume the body or close the response, otherwise get netty ByteBuf leak
129+
// warnings:
130+
// io.netty.util.ResourceLeakDetector - LEAK: ByteBuf.release() was not called before
131+
// it's garbage-collected (see https://github.com/Azure/azure-sdk-for-java/issues/10467)
128132
response.close();
129133
}
130134
}

0 commit comments

Comments
 (0)