use of com.hotels.styx.api.extension.service.ConnectionPoolSettings in project styx by ExpediaGroup.
the class SimpleConnectionPoolTest method givesReturnedConnectionsToPendingSubscibers.
@Test
public void givesReturnedConnectionsToPendingSubscibers() throws ExecutionException, InterruptedException, TimeoutException {
when(connectionFactory.createConnection(any(Origin.class), any(ConnectionSettings.class))).thenReturn(Mono.just(connection1)).thenReturn(Mono.just(connection2)).thenReturn(Mono.just(connection3)).thenReturn(Mono.just(connection4));
ConnectionPoolSettings poolSettings = new ConnectionPoolSettings.Builder().maxConnectionsPerHost(2).maxPendingConnectionsPerHost(2).build();
SimpleConnectionPool pool = new SimpleConnectionPool(origin, poolSettings, connectionFactory);
// Saturate active connections:
CompletableFuture<Connection> active1 = Mono.from(pool.borrowConnection()).toFuture();
CompletableFuture<Connection> active2 = Mono.from(pool.borrowConnection()).toFuture();
assertTrue(active1.isDone());
assertTrue(active2.isDone());
assertEquals(pool.stats().connectionAttempts(), 2);
assertEquals(pool.stats().busyConnectionCount(), 2);
// Create two pending connections
CompletableFuture<Connection> pending1 = Mono.from(pool.borrowConnection()).toFuture();
CompletableFuture<Connection> pending2 = Mono.from(pool.borrowConnection()).toFuture();
assertFalse(pending1.isDone());
assertFalse(pending2.isDone());
assertEquals(pool.stats().connectionAttempts(), 2);
assertEquals(pool.stats().busyConnectionCount(), 2);
assertEquals(pool.stats().pendingConnectionCount(), 2);
// Return active connections
pool.returnConnection(active1.get());
pool.returnConnection(active2.get());
// Show that returned connections are given to pending subscribers
assertEquals(pending1.get(), connection1);
assertEquals(pending2.get(), connection2);
assertEquals(pool.stats().connectionAttempts(), 2);
assertEquals(pool.stats().busyConnectionCount(), 2);
assertEquals(pool.stats().pendingConnectionCount(), 0);
}
use of com.hotels.styx.api.extension.service.ConnectionPoolSettings in project styx by ExpediaGroup.
the class SimpleConnectionPoolTest method emitsExceptionWhenPendingConnectionTimesOut.
@Test
public void emitsExceptionWhenPendingConnectionTimesOut() {
EmitterProcessor<Connection> processor = EmitterProcessor.create();
when(connectionFactory.createConnection(any(Origin.class), any(ConnectionSettings.class))).thenReturn(Mono.from(processor));
ConnectionPoolSettings poolSettings = new ConnectionPoolSettings.Builder().pendingConnectionTimeout(500, MILLISECONDS).build();
SimpleConnectionPool pool = new SimpleConnectionPool(origin, poolSettings, connectionFactory);
StepVerifier.create(pool.borrowConnection()).expectError(MaxPendingConnectionTimeoutException.class).verifyThenAssertThat().tookMoreThan(Duration.ofMillis(500));
// And then ensure connection is placed in the active queue:
processor.onNext(mock(Connection.class));
assertEquals(pool.stats().availableConnectionCount(), 1);
assertEquals(pool.stats().pendingConnectionCount(), 0);
assertEquals(pool.stats().busyConnectionCount(), 0);
assertEquals(pool.stats().connectionAttempts(), 1);
}
use of com.hotels.styx.api.extension.service.ConnectionPoolSettings in project styx by ExpediaGroup.
the class SimpleConnectionPoolTest method shouldNotHandoutConnectionToCancelledSubscriberWhenCreatingNewConnection.
@Test
public void shouldNotHandoutConnectionToCancelledSubscriberWhenCreatingNewConnection() throws Exception {
when(connectionFactory.createConnection(any(Origin.class), any(ConnectionSettings.class))).thenReturn(Mono.just(connection1));
ConnectionPoolSettings poolSettings = new ConnectionPoolSettings.Builder().pendingConnectionTimeout(100, MILLISECONDS).build();
SimpleConnectionPool simpleConnectionPool = new SimpleConnectionPool(origin, poolSettings, connectionFactory);
SimpleConnectionPool pool = spy(simpleConnectionPool);
when(pool.dequeue()).thenAnswer(new AnswersWithDelay(200, new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return invocation.callRealMethod();
}
}));
StepVerifier.create(pool.borrowConnection()).expectError(MaxPendingConnectionTimeoutException.class).verify();
assertEquals(pool.stats().availableConnectionCount(), 1);
// Waiting subscribers
assertEquals(pool.stats().pendingConnectionCount(), 0);
// Borrowed count
assertEquals(pool.stats().busyConnectionCount(), 0);
}
use of com.hotels.styx.api.extension.service.ConnectionPoolSettings in project styx by ExpediaGroup.
the class BackendServicesRouter method onChange.
@Override
public void onChange(Registry.Changes<BackendService> changes) {
changes.removed().forEach(backendService -> routes.remove(backendService.path()).close());
concatenatedForEach(changes.added(), changes.updated(), backendService -> {
ProxyToClientPipeline pipeline = routes.get(backendService.path());
if (pipeline != null) {
pipeline.close();
}
boolean requestLoggingEnabled = environment.styxConfig().get("request-logging.outbound.enabled", Boolean.class).orElse(false);
boolean longFormat = environment.styxConfig().get("request-logging.outbound.longFormat", Boolean.class).orElse(false);
OriginStatsFactory originStatsFactory = new CachingOriginStatsFactory(environment.centralisedMetrics());
ConnectionPoolSettings poolSettings = backendService.connectionPoolConfig();
Connection.Factory connectionFactory = connectionFactory(backendService, requestLoggingEnabled, longFormat, originStatsFactory, poolSettings.connectionExpirationSeconds());
ConnectionPool.Factory connectionPoolFactory = new SimpleConnectionPoolFactory.Builder().connectionFactory(connectionFactory).connectionPoolSettings(backendService.connectionPoolConfig()).metrics(environment.centralisedMetrics()).build();
OriginHealthStatusMonitor healthStatusMonitor = healthStatusMonitor(backendService);
OriginsInventory inventory = new OriginsInventory.Builder(backendService.id()).eventBus(environment.eventBus()).metrics(environment.centralisedMetrics()).connectionPoolFactory(connectionPoolFactory).originHealthMonitor(healthStatusMonitor).initialOrigins(backendService.origins()).hostClientFactory(StyxHostHttpClient::create).build();
pipeline = new ProxyToClientPipeline(newClientHandler(backendService, inventory, originStatsFactory), () -> {
inventory.close();
healthStatusMonitor.stop();
});
routes.put(backendService.path(), pipeline);
LOG.info("added path={} current routes={}", backendService.path(), routes.keySet());
});
}
Aggregations