All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.arangodb.shaded.vertx.core.http.impl.SharedClientHttpStreamEndpoint Maven / Gradle / Ivy
/*
* Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*/
package com.arangodb.shaded.vertx.core.http.impl;
import com.arangodb.shaded.vertx.core.AsyncResult;
import com.arangodb.shaded.vertx.core.Future;
import com.arangodb.shaded.vertx.core.Handler;
import com.arangodb.shaded.vertx.core.http.HttpConnection;
import com.arangodb.shaded.vertx.core.http.HttpVersion;
import com.arangodb.shaded.vertx.core.impl.ContextInternal;
import com.arangodb.shaded.vertx.core.impl.EventLoopContext;
import com.arangodb.shaded.vertx.core.net.impl.pool.ConnectResult;
import com.arangodb.shaded.vertx.core.net.impl.pool.ConnectionPool;
import com.arangodb.shaded.vertx.core.net.impl.pool.PoolConnection;
import com.arangodb.shaded.vertx.core.net.impl.pool.PoolConnector;
import com.arangodb.shaded.vertx.core.net.impl.pool.Lease;
import com.arangodb.shaded.vertx.core.net.impl.pool.PoolWaiter;
import com.arangodb.shaded.vertx.core.spi.metrics.ClientMetrics;
import java.util.List;
import java.util.function.BiFunction;
/**
* @author Julien Viet
*/
class SharedClientHttpStreamEndpoint extends ClientHttpEndpointBase> implements PoolConnector {
/**
* LIFO pool selector.
*/
private static final BiFunction, List>, PoolConnection> LIFO_SELECTOR = (waiter, connections) -> {
int size = connections.size();
PoolConnection selected = null;
long last = 0L;
for (int i = 0; i < size; i++) {
PoolConnection pooled = connections.get(i);
if (pooled.available() > 0) {
HttpClientConnection conn = pooled.get();
if (selected == null) {
selected = pooled;
} else {
if (conn.lastResponseReceivedTimestamp() > last) {
selected = pooled;
}
}
}
}
return selected;
};
private final HttpClientImpl client;
private final HttpChannelConnector connector;
private final ConnectionPool pool;
public SharedClientHttpStreamEndpoint(HttpClientImpl client,
ClientMetrics metrics,
int queueMaxSize,
int http1MaxSize,
int http2MaxSize,
HttpChannelConnector connector,
Runnable dispose) {
super(metrics, dispose);
ConnectionPool pool = ConnectionPool.pool(this, new int[]{http1MaxSize, http2MaxSize}, queueMaxSize)
.connectionSelector(LIFO_SELECTOR).contextProvider(client.contextProvider());
this.client = client;
this.connector = connector;
this.pool = pool;
}
@Override
public void connect(EventLoopContext context, Listener listener, Handler>> handler) {
connector.httpConnect(context, ar -> {
if (ar.succeeded()) {
incRefCount();
HttpClientConnection connection = ar.result();
connection.evictionHandler(v -> {
decRefCount();
listener.onRemove();
});
connection.concurrencyChangeHandler(listener::onConcurrencyChange);
long capacity = connection.concurrency();
Handler connectionHandler = client.connectionHandler();
if (connectionHandler != null) {
context.emit(connection, connectionHandler);
}
int idx;
if (connection instanceof Http1xClientConnection) {
idx = 0;
} else {
idx = 1;
}
handler.handle(Future.succeededFuture(new ConnectResult<>(connection, capacity, idx)));
} else {
handler.handle(Future.failedFuture(ar.cause()));
}
});
}
@Override
public boolean isValid(HttpClientConnection connection) {
return connection.isValid();
}
void checkExpired() {
pool.evict(conn -> !conn.isValid(), ar -> {
if (ar.succeeded()) {
List lst = ar.result();
lst.forEach(HttpConnection::close);
}
});
}
private class Request implements PoolWaiter.Listener, Handler>> {
private final ContextInternal context;
private final HttpVersion protocol;
private final long timeout;
private final Handler>> handler;
private long timerID;
Request(ContextInternal context, HttpVersion protocol, long timeout, Handler>> handler) {
this.context = context;
this.protocol = protocol;
this.timeout = timeout;
this.handler = handler;
this.timerID = -1L;
}
@Override
public void onEnqueue(PoolWaiter waiter) {
onConnect(waiter);
}
@Override
public void onConnect(PoolWaiter waiter) {
if (timeout > 0L && timerID == -1L) {
timerID = context.setTimer(timeout, id -> {
pool.cancel(waiter, ar -> {
if (ar.succeeded() && ar.result()) {
handler.handle(Future.failedFuture(new NoStackTraceTimeoutException("The timeout of " + timeout + " ms has been exceeded when getting a connection to " + connector.server())));
}
});
});
}
}
@Override
public void handle(AsyncResult> ar) {
if (timerID >= 0) {
context.owner().cancelTimer(timerID);
}
handler.handle(ar);
}
void acquire() {
pool.acquire(context, this, protocol == HttpVersion.HTTP_2 ? 1 : 0, this);
}
}
@Override
public void requestConnection2(ContextInternal ctx, long timeout, Handler>> handler) {
Request request = new Request(ctx, client.options().getProtocolVersion(), timeout, handler);
request.acquire();
}
}