Skip to content

Commit

Permalink
Merge branch 'read-timeouts' into 'master'
Browse files Browse the repository at this point in the history
Timeouts settings forwarding

See merge request hercules/hercules!422
  • Loading branch information
petr-stb committed Sep 13, 2022
2 parents ced27fa + e178759 commit 0015fb5
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 43 deletions.
12 changes: 12 additions & 0 deletions hercules-elastic-adapter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,18 @@ HTTP Server binds on host:port are defined in Main Application settings.

`http.server.connection.threshold` - maximum active http connections, default value: `100000`

`http.server.readTimeout` - Configure a read timeout for a socket, in milliseconds.

`http.server.writeTimeout` - Configure a write timeout for a socket, in milliseconds.

`http.server.requestParseTimeout` - The maximum allowed time of reading HTTP request in milliseconds.
`-1` or missing value disables this functionality.

`http.server.idleTimeout` - The idle timeout in milliseconds after which the channel will be closed.
If the underlying channel already has a read or write timeout set the smaller of the two values will be used for read/write timeouts.

`http.server.noRequestTimeout` - The amount of time the connection can be idle with no current requests before it is closed.

### Graphite metrics reporter settings
`metrics.graphite.server.addr` - hostname of graphite instance to which metrics are sent, default value: `localhost`

Expand Down
12 changes: 12 additions & 0 deletions hercules-gate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,18 @@ HTTP Server binds on `<host>:<port>` are defined in Main Application settings.

`http.server.throttling.requestTimeout` - timeout for request, which capacity throttling more then permissible, default value: `5000`

`http.server.readTimeout` - Configure a read timeout for a socket, in milliseconds.

`http.server.writeTimeout` - Configure a write timeout for a socket, in milliseconds.

`http.server.requestParseTimeout` - The maximum allowed time of reading HTTP request in milliseconds.
`-1` or missing value disables this functionality.

`http.server.idleTimeout` - The idle timeout in milliseconds after which the channel will be closed.
If the underlying channel already has a read or write timeout set the smaller of the two values will be used for read/write timeouts.

`http.server.noRequestTimeout` - The amount of time the connection can be idle with no current requests before it is closed.

### Validation settings

`validation.max.event.size` - max size of Hercules event, value must be consistent with broker setting `max.message.bytes`, default value: `500000`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* @author Gregory Koshelev
*/
public abstract class HttpServer implements Lifecycle {

private final AtomicReference<HttpServerState> state = new AtomicReference<>(HttpServerState.INIT);

protected final String host;
Expand Down Expand Up @@ -66,35 +67,46 @@ protected boolean stopInternal(long timeout, TimeUnit unit) {
}

public static final class Props {
public static final Parameter<Long> MAX_CONTENT_LENGTH =
Parameter.longParameter("maxContentLength").
withDefault(HttpServerDefaults.DEFAULT_MAX_CONTENT_LENGTH).
withValidator(LongValidators.positive()).
build();

public static final Parameter<Integer> CONNECTION_THRESHOLD =
Parameter.integerParameter("connection.threshold").
withDefault(HttpServerDefaults.DEFAULT_CONNECTION_THRESHOLD).
withValidator(IntegerValidators.positive()).
build();

public static final Parameter<Integer> IO_THREADS =
Parameter.integerParameter("ioThreads").
withValidator(IntegerValidators.positive()).
build();

public static final Parameter<Integer> WORKER_THREADS =
Parameter.integerParameter("workerThreads").
withValidator(IntegerValidators.positive()).
build();

public static final Parameter<String> ROOT_PATH =
Parameter.stringParameter("rootPath").
withDefault("/").
withValidator(Validators.and(
Validators.notNull(),
x -> x.startsWith("/") ? ValidationResult.ok() : ValidationResult.error("Should start with '/'"))).
build();

/**
* Maximum value of content length of HTTP-requests.
*/
public static final Parameter<Long> MAX_CONTENT_LENGTH = Parameter.longParameter("maxContentLength")
.withDefault(HttpServerDefaults.DEFAULT_MAX_CONTENT_LENGTH)
.withValidator(LongValidators.positive())
.build();

/**
* Maximum simultaneous connections count.
*/
public static final Parameter<Integer> CONNECTION_THRESHOLD = Parameter.integerParameter("connection.threshold")
.withDefault(HttpServerDefaults.DEFAULT_CONNECTION_THRESHOLD)
.withValidator(IntegerValidators.positive())
.build();

/**
* Count of IO threads.
*/
public static final Parameter<Integer> IO_THREADS = Parameter.integerParameter("ioThreads")
.withValidator(IntegerValidators.positive())
.build();

/**
* Count of worker threads.
*/
public static final Parameter<Integer> WORKER_THREADS = Parameter.integerParameter("workerThreads")
.withValidator(IntegerValidators.positive())
.build();

/**
* Root path of HTTP-server.
*/
public static final Parameter<String> ROOT_PATH = Parameter.stringParameter("rootPath")
.withDefault("/")
.withValidator(Validators.and(
Validators.notNull(),
x -> x.startsWith("/") ? ValidationResult.ok() : ValidationResult.error("Should start with '/'")))
.build();

private Props() {
/* static class */
Expand Down
12 changes: 12 additions & 0 deletions hercules-management-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,18 @@ See Curator Config from Apache Curator documentation. Main settings are presente

`http.server.rootPath` - base url, default value: `/`

`http.server.readTimeout` - Configure a read timeout for a socket, in milliseconds.

`http.server.writeTimeout` - Configure a write timeout for a socket, in milliseconds.

`http.server.requestParseTimeout` - The maximum allowed time of reading HTTP request in milliseconds.
`-1` or missing value disables this functionality.

`http.server.idleTimeout` - The idle timeout in milliseconds after which the channel will be closed.
If the underlying channel already has a read or write timeout set the smaller of the two values will be used for read/write timeouts.

`http.server.noRequestTimeout` - The amount of time the connection can be idle with no current requests before it is closed.

### Management API settings
`keys` - master API keys.

Expand Down
12 changes: 12 additions & 0 deletions hercules-stream-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,18 @@ See Apache Curator Config from Apache Curator documentation. Main settings are p

`http.server.rootPath` - base url, default value: `/`

`http.server.readTimeout` - Configure a read timeout for a socket, in milliseconds.

`http.server.writeTimeout` - Configure a write timeout for a socket, in milliseconds.

`http.server.requestParseTimeout` - The maximum allowed time of reading HTTP request in milliseconds.
`-1` or missing value disables this functionality.

`http.server.idleTimeout` - The idle timeout in milliseconds after which the channel will be closed.
If the underlying channel already has a read or write timeout set the smaller of the two values will be used for read/write timeouts.

`http.server.noRequestTimeout` - The amount of time the connection can be idle with no current requests before it is closed.

### Stream API settings
`stream.api.pool.size` - consumers pool size. Default value: `4`.

Expand Down
12 changes: 12 additions & 0 deletions hercules-tracing-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,18 @@ default value: `localhost:8123`

`http.server.rootPath` - base url, default value: `/`

`http.server.readTimeout` - Configure a read timeout for a socket, in milliseconds.

`http.server.writeTimeout` - Configure a write timeout for a socket, in milliseconds.

`http.server.requestParseTimeout` - The maximum allowed time of reading HTTP request in milliseconds.
`-1` or missing value disables this functionality.

`http.server.idleTimeout` - The idle timeout in milliseconds after which the channel will be closed.
If the underlying channel already has a read or write timeout set the smaller of the two values will be used for read/write timeouts.

`http.server.noRequestTimeout` - The amount of time the connection can be idle with no current requests before it is closed.

## Command line
`java $JAVA_OPTS -jar hercules-sentry-sink.jar application.properties=file://path/to/properties/file`

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ru.kontur.vostok.hercules.undertow.util;

import io.undertow.Undertow;
import io.undertow.UndertowOptions;
import io.undertow.server.HttpServerExchange;
import org.xnio.Options;
import ru.kontur.vostok.hercules.http.HttpServer;
Expand All @@ -17,6 +18,7 @@
* @author Gregory Koshelev
*/
public class UndertowHttpServer extends HttpServer {

private Undertow undertow;

public UndertowHttpServer(String host, int port, Properties properties, HttpHandler handler) {
Expand All @@ -26,23 +28,28 @@ public UndertowHttpServer(String host, int port, Properties properties, HttpHand
@Override
protected void startInternal() {
int connectionThreshold = PropertiesUtil.get(Props.CONNECTION_THRESHOLD, properties).get();
Parameter<Integer>.ParameterValue ioThreads = PropertiesUtil.get(Props.IO_THREADS, properties);
Parameter<Integer>.ParameterValue workerThreads = PropertiesUtil.get(Props.WORKER_THREADS, properties);

final ExceptionHandler exceptionHandler = new ExceptionHandler(handler);

Undertow.Builder builder = Undertow.builder().
addHttpListener(port, host).
setHandler(exchange -> exceptionHandler.handle(wrap(exchange))).
setSocketOption(Options.CONNECTION_HIGH_WATER, connectionThreshold).
setSocketOption(Options.CONNECTION_LOW_WATER, connectionThreshold);
Undertow.Builder builder = Undertow.builder()
.addHttpListener(port, host)
.setHandler(exchange -> exceptionHandler.handle(wrap(exchange)))
.setSocketOption(Options.CONNECTION_HIGH_WATER, connectionThreshold)
.setSocketOption(Options.CONNECTION_LOW_WATER, connectionThreshold);

if (!ioThreads.isEmpty()) {
builder.setIoThreads(ioThreads.get());
}
if (!workerThreads.isEmpty()) {
builder.setWorkerThreads(workerThreads.get());
}
PropertiesUtil.get(Props.IO_THREADS, properties)
.ifPresent(builder::setIoThreads);
PropertiesUtil.get(Props.WORKER_THREADS, properties)
.ifPresent(builder::setWorkerThreads);
PropertiesUtil.get(UndertowProps.READ_TIMEOUT, properties)
.ifPresent(value -> builder.setSocketOption(Options.READ_TIMEOUT, value));
PropertiesUtil.get(UndertowProps.WRITE_TIMEOUT, properties)
.ifPresent(value -> builder.setSocketOption(Options.WRITE_TIMEOUT, value));
PropertiesUtil.get(UndertowProps.REQUEST_PARSE_TIMEOUT, properties)
.ifPresent(value -> builder.setServerOption(UndertowOptions.REQUEST_PARSE_TIMEOUT, value));
PropertiesUtil.get(UndertowProps.IDLE_TIMEOUT, properties)
.ifPresent(value -> builder.setServerOption(UndertowOptions.IDLE_TIMEOUT, value));
PropertiesUtil.get(UndertowProps.NO_REQUEST_TIMEOUT, properties)
.ifPresent(value -> builder.setServerOption(UndertowOptions.NO_REQUEST_TIMEOUT, value));

undertow = builder.build();

Expand All @@ -58,4 +65,58 @@ protected boolean stopInternal(long timeout, TimeUnit unit) {
private static HttpServerRequest wrap(HttpServerExchange exchange) {
return new UndertowHttpServerRequest(exchange);
}

/**
* Specific Undertow properties.
*/
public static class UndertowProps {

/**
* Configure a read timeout for a socket, in milliseconds.
*
* If the given amount of time elapses without a successful read taking place, the socket's next read will throw a ReadTimeoutException.
*
* @see Options#READ_TIMEOUT
*/
public static final Parameter<Integer> READ_TIMEOUT = Parameter.integerParameter("readTimeout")
.build();

/**
* Configure a write timeout for a socket, in milliseconds.
*
* If the given amount of time elapses without a successful write taking place, the socket's next write will throw a WriteTimeoutException.
*
* @see Options#WRITE_TIMEOUT
*/
public static final Parameter<Integer> WRITE_TIMEOUT = Parameter.integerParameter("writeTimeout")
.build();

/**
* The maximum allowed time of reading HTTP request in milliseconds.
*
* -1 or missing value disables this functionality.
*
* @see UndertowOptions#REQUEST_PARSE_TIMEOUT
*/
public static final Parameter<Integer> REQUEST_PARSE_TIMEOUT = Parameter.integerParameter("requestParseTimeout")
.build();

/**
* The idle timeout in milliseconds after which the channel will be closed.
*
* If the underlying channel already has a read or write timeout set the smaller of the two values will be used for read/write timeouts.
*
* @see UndertowOptions#IDLE_TIMEOUT
*/
public static final Parameter<Integer> IDLE_TIMEOUT = Parameter.integerParameter("idleTimeout")
.build();

/**
* The amount of time the connection can be idle with no current requests before it is closed.
*
* @see UndertowOptions#NO_REQUEST_TIMEOUT
*/
public static final Parameter<Integer> NO_REQUEST_TIMEOUT = Parameter.integerParameter("noRequestTimeout")
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import ru.kontur.vostok.hercules.util.validation.Validator;
import ru.kontur.vostok.hercules.util.validation.Validators;

import java.util.function.Consumer;


/**
* Parameter
Expand Down Expand Up @@ -431,5 +433,16 @@ public boolean isEmpty() {
public Parameter<T> parameter() {
return Parameter.this;
}

/**
* If a value is present and validation result is ok, performs the given action with the value, otherwise does nothing.
*
* @param consumer Consumer for a value.
*/
public void ifPresent(Consumer<? super T> consumer) {
if (!isEmpty() && result.isOk()) {
consumer.accept(value);
}
}
}
}

0 comments on commit 0015fb5

Please sign in to comment.