Skip to content

Commit f339c01

Browse files
committed
ConnectionContext Cleanup
This change adds a dispose() method on the DefaultConnectionContext in order to cleanup any cached resources like connection and thread pools. This method is also marked as @PreDestroy so any DefaultConnectionContext created as a Spring (or EJB) bean will be automatically disposed as part of the standard application lifecycle. This implementation is a temporary solution until reactor/reactor-netty#88 is implemented and available. [resolves #745]
1 parent a3350c9 commit f339c01

File tree

4 files changed

+37
-13
lines changed

4 files changed

+37
-13
lines changed

cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/_DefaultConnectionContext.java

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import reactor.ipc.netty.resources.LoopResources;
3838
import reactor.ipc.netty.resources.PoolResources;
3939

40+
import javax.annotation.PreDestroy;
4041
import java.time.Duration;
4142
import java.util.List;
4243
import java.util.Map;
@@ -67,6 +68,15 @@ abstract class _DefaultConnectionContext implements ConnectionContext {
6768

6869
private static final int UNDEFINED_PORT = -1;
6970

71+
/**
72+
* Disposes resources created to service this connection context
73+
*/
74+
@PreDestroy
75+
public final void dispose() {
76+
getConnectionPool().ifPresent(PoolResources::dispose);
77+
getThreadPool().dispose();
78+
}
79+
7080
/**
7181
* The number of connections to use when processing requests and responses. Setting this to `null` disables connection pooling.
7282
*/
@@ -81,12 +91,12 @@ public Integer getConnectionPoolSize() {
8191
public HttpClient getHttpClient() {
8292
return HttpClient.create(options -> {
8393
options
84-
.loopResources(LoopResources.create("cloudfoundry-client", getThreadPoolSize(), true))
94+
.loopResources(getThreadPool())
8595
.option(SO_SNDBUF, SEND_BUFFER_SIZE)
8696
.option(SO_RCVBUF, RECEIVE_BUFFER_SIZE)
8797
.disablePool();
8898

89-
Optional.ofNullable(getConnectionPoolSize()).ifPresent(connectionPoolSize -> options.poolResources(PoolResources.fixed("cloudfoundry-client", connectionPoolSize)));
99+
getConnectionPool().ifPresent(options::poolResources);
90100
getKeepAlive().ifPresent(keepAlive -> options.option(SO_KEEPALIVE, keepAlive));
91101
getProxyConfiguration().ifPresent(c -> options.proxy(ClientOptions.Proxy.HTTP, c.getHost(), c.getPort().orElse(null), c.getUsername().orElse(null), u -> c.getPassword().orElse(null)));
92102
getConnectTimeout().ifPresent(socketTimeout -> options.option(CONNECT_TIMEOUT_MILLIS, (int) socketTimeout.toMillis()));
@@ -115,15 +125,6 @@ public Integer getPort() {
115125
return DEFAULT_PORT;
116126
}
117127

118-
@Override
119-
public Mono<String> getRoot(String key) {
120-
return getInfo()
121-
.map(info -> normalize(UriComponentsBuilder.fromUriString(info.get(key)), getScheme()))
122-
.doOnNext(components -> trust(components, getSslCertificateTruster()))
123-
.map(UriComponents::toUriString)
124-
.cache();
125-
}
126-
127128
@Value.Derived
128129
public Mono<String> getRoot() {
129130
Integer port = getPort();
@@ -138,6 +139,15 @@ public Mono<String> getRoot() {
138139
return Mono.just(components.toUriString());
139140
}
140141

142+
@Override
143+
public Mono<String> getRoot(String key) {
144+
return getInfo()
145+
.map(info -> normalize(UriComponentsBuilder.fromUriString(info.get(key)), getScheme()))
146+
.doOnNext(components -> trust(components, getSslCertificateTruster()))
147+
.map(UriComponents::toUriString)
148+
.cache();
149+
}
150+
141151
/**
142152
* The number of worker threads to use when processing requests and responses
143153
*/
@@ -165,6 +175,12 @@ void checkForValidApiHost() {
165175
*/
166176
abstract Optional<Duration> getConnectTimeout();
167177

178+
@Value.Derived
179+
Optional<PoolResources> getConnectionPool() {
180+
return Optional.ofNullable(getConnectionPoolSize())
181+
.map(connectionPoolSize -> PoolResources.fixed("cloudfoundry-client", connectionPoolSize));
182+
}
183+
168184
@SuppressWarnings("unchecked")
169185
@Value.Derived
170186
Mono<Map<String, String>> getInfo() {
@@ -229,6 +245,11 @@ Optional<SslCertificateTruster> getSslCertificateTruster() {
229245
*/
230246
abstract Optional<Duration> getSslHandshakeTimeout();
231247

248+
@Value.Derived
249+
LoopResources getThreadPool() {
250+
return LoopResources.create("cloudfoundry-client", getThreadPoolSize(), true);
251+
}
252+
232253
private static void trust(UriComponents components, Optional<SslCertificateTruster> sslCertificateTruster) {
233254
sslCertificateTruster.ifPresent(t -> t.trust(components.getHost(), components.getPort(), Duration.ofSeconds(30)));
234255
}

cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/_ReactorCloudFoundryClient.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@
9595
import org.immutables.value.Value;
9696
import reactor.core.publisher.Mono;
9797

98+
import javax.annotation.PostConstruct;
99+
98100
/**
99101
* The Reactor-based implementation of {@link CloudFoundryClient}
100102
*/
@@ -125,6 +127,7 @@ public Buildpacks buildpacks() {
125127
return new ReactorBuildpacks(getConnectionContext(), getRoot(), getTokenProvider());
126128
}
127129

130+
@PostConstruct
128131
public void checkCompatibility() {
129132
new CloudFoundryClientCompatibilityChecker(info()).check();
130133
}

integration-test/src/test/java/org/cloudfoundry/ExampleConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
@EnableAutoConfiguration
4040
public class ExampleConfiguration {
4141

42-
@Bean(initMethod = "checkCompatibility")
42+
@Bean
4343
@Lazy
4444
ReactorCloudFoundryClient cloudFoundryClient(ConnectionContext connectionContext, TokenProvider tokenProvider) {
4545
return ReactorCloudFoundryClient.builder()

integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ CloudFoundryCleaner cloudFoundryCleaner(@Qualifier("admin") CloudFoundryClient c
208208
return new CloudFoundryCleaner(cloudFoundryClient, nameFactory, uaaClient);
209209
}
210210

211-
@Bean(initMethod = "checkCompatibility")
211+
@Bean
212212
ReactorCloudFoundryClient cloudFoundryClient(ConnectionContext connectionContext, TokenProvider tokenProvider) {
213213
return ReactorCloudFoundryClient.builder()
214214
.connectionContext(connectionContext)

0 commit comments

Comments
 (0)