Skip to content

Commit 9910df8

Browse files
committed
Remove observation context from ClientRequest
Prior to this commit, gh-31609 added the current observation context as a request attribute for `WebClient` calls. While it was not confirmed as the main cause, this feature was linked to several reports of memory leaks. This would indeed attach more memory to the request object graph at runtime - although it shouldn't prevent its collection by the GC. This commit removes this feature and instead developers should get the current observation from the reactor context if they wish to interact with it. Closes gh-32198
1 parent 88b3844 commit 9910df8

File tree

3 files changed

+1
-41
lines changed

3 files changed

+1
-41
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientRequestObservationContext.java

-21
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
package org.springframework.web.reactive.function.client;
1818

19-
import java.util.Optional;
20-
2119
import io.micrometer.observation.transport.RequestReplySenderContext;
2220

2321
import org.springframework.lang.Nullable;
@@ -35,14 +33,6 @@
3533
*/
3634
public class ClientRequestObservationContext extends RequestReplySenderContext<ClientRequest.Builder, ClientResponse> {
3735

38-
/**
39-
* Name of the request attribute holding the {@link ClientRequestObservationContext context}
40-
* for the current observation.
41-
* @since 6.0.15
42-
*/
43-
public static final String CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE = ClientRequestObservationContext.class.getName();
44-
45-
4636
@Nullable
4737
private String uriTemplate;
4838

@@ -127,15 +117,4 @@ public ClientRequest getRequest() {
127117
}
128118

129119

130-
/**
131-
* Get the current {@link ClientRequestObservationContext observation context}
132-
* from the given request, if available.
133-
* @param request the current client request
134-
* @return the current observation context
135-
* @since 6.0.15
136-
*/
137-
public static Optional<ClientRequestObservationContext> findCurrent(ClientRequest request) {
138-
return Optional.ofNullable((ClientRequestObservationContext) request.attributes().get(CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE));
139-
}
140-
141120
}

spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -450,9 +450,7 @@ public Mono<ClientResponse> exchange() {
450450
if (filterFunctions != null) {
451451
filterFunction = filterFunctions.andThen(filterFunction);
452452
}
453-
ClientRequest request = requestBuilder
454-
.attribute(ClientRequestObservationContext.CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE, observationContext)
455-
.build();
453+
ClientRequest request = requestBuilder.build();
456454
observationContext.setUriTemplate((String) request.attribute(URI_TEMPLATE_ATTRIBUTE).orElse(null));
457455
observationContext.setRequest(request);
458456
Mono<ClientResponse> responseMono = filterFunction.apply(exchangeFunction)

spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientObservationTests.java

-17
Original file line numberDiff line numberDiff line change
@@ -148,23 +148,6 @@ void setsCurrentObservationInReactorContext() {
148148
verifyAndGetRequest();
149149
}
150150

151-
@Test
152-
void setsCurrentObservationContextAsRequestAttribute() {
153-
ExchangeFilterFunction assertionFilter = (request, chain) -> {
154-
Optional<ClientRequestObservationContext> observationContext = ClientRequestObservationContext.findCurrent(request);
155-
assertThat(observationContext).isPresent();
156-
return chain.exchange(request).contextWrite(context -> {
157-
Observation currentObservation = context.get(ObservationThreadLocalAccessor.KEY);
158-
assertThat(currentObservation.getContext()).isEqualTo(observationContext.get());
159-
return context;
160-
});
161-
};
162-
this.builder.filter(assertionFilter).build().get().uri("/resource/{id}", 42)
163-
.retrieve().bodyToMono(Void.class)
164-
.block(Duration.ofSeconds(10));
165-
verifyAndGetRequest();
166-
}
167-
168151
@Test
169152
void recordsObservationWithResponseDetailsWhenFilterFunctionErrors() {
170153
ExchangeFilterFunction errorFunction = (req, next) -> next.exchange(req).then(Mono.error(new IllegalStateException()));

0 commit comments

Comments
 (0)