Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,16 @@ default B prettyPrint() {
return prettyPrint(true);
}

/**
* Timeout to establish a connection to the Docling Serve API.
*/
B connectTimeout(Duration connectTimeout);

/**
* Timeout for receiving a response from the Docling Serve API.
*/
B readTimeout(Duration readTimeout);

/**
* Sets the polling interval for async operations.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
import static ai.docling.serve.api.util.Utils.isNullOrBlank;
import static ai.docling.serve.api.util.Utils.isNullOrEmpty;

import java.time.Duration;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;

import org.jspecify.annotations.Nullable;

/**
* Utility class for validating method arguments.
*/
Expand Down Expand Up @@ -271,4 +274,16 @@ public static long ensureBetween(Long i, long min, long max, String name) {
}
return i;
}

/**
* Ensures that the given duration is positive.
* @param duration The duration to check.
* @throws IllegalArgumentException if the duration is negative or zero.
*/
public static void ensurePositiveDuration(@Nullable Duration duration, String name) {
if (duration == null || duration.isNegative() || duration.isZero()) {
throw new IllegalArgumentException("%s must be a positive duration".formatted(name));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
Expand Down Expand Up @@ -261,4 +262,16 @@ void ensure_between_long() {
.withMessageContaining("test must be between 0 and 1, but is: -1");
}
}

@Test
void ensurePositiveDuration() {
ValidationUtils.ensurePositiveDuration(Duration.ofSeconds(1), "test");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> ValidationUtils.ensurePositiveDuration(Duration.ofSeconds(-1), "test"))
.withMessageContaining("test must be a positive duration");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> ValidationUtils.ensurePositiveDuration(Duration.ofSeconds(0), "test"))
.withMessageContaining("test must be a positive duration");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import ai.docling.serve.api.task.request.TaskStatusPollRequest;
import ai.docling.serve.api.task.response.TaskStatusPollResponse;
import ai.docling.serve.api.util.Utils;
import ai.docling.serve.api.util.ValidationUtils;
import ai.docling.serve.api.validation.ValidationError;
import ai.docling.serve.api.validation.ValidationException;
import ai.docling.serve.client.operations.ChunkOperations;
Expand Down Expand Up @@ -79,6 +80,8 @@ public abstract class DoclingServeClient extends HttpOperations implements Docli
private final boolean logResponses;
private final boolean prettyPrintJson;
private final @Nullable String apiKey;
private final Duration connectTimeout;
private final Duration readTimeout;
private final Duration asyncPollInterval;
private final Duration asyncTimeout;

Expand All @@ -89,6 +92,11 @@ public abstract class DoclingServeClient extends HttpOperations implements Docli
private final TaskOperations taskOps;

protected DoclingServeClient(DoclingServeClientBuilder builder) {
ValidationUtils.ensurePositiveDuration(builder.connectTimeout, "connectTimeout");
ValidationUtils.ensurePositiveDuration(builder.readTimeout, "readTimeout");
ValidationUtils.ensurePositiveDuration(builder.asyncPollInterval, "asyncPollInterval");
ValidationUtils.ensurePositiveDuration(builder.asyncTimeout, "asyncTimeout");

var base = ensureNotNull(builder.baseUrl, "baseUrl");

if (Objects.equals(base.getScheme(), "http")) {
Expand All @@ -102,7 +110,13 @@ protected DoclingServeClient(DoclingServeClientBuilder builder) {
URI.create(base + "/") :
base;

this.httpClient = ensureNotNull(builder.httpClientBuilder, "httpClientBuilder").build();
this.connectTimeout = builder.connectTimeout;
this.readTimeout = builder.readTimeout;

this.httpClient = ensureNotNull(builder.httpClientBuilder, "httpClientBuilder")
.connectTimeout(connectTimeout)
.build();

this.logRequests = builder.logRequests;
this.logResponses = builder.logResponses;
this.prettyPrintJson = builder.prettyPrintJson;
Expand Down Expand Up @@ -234,7 +248,8 @@ protected <I, O> O executeGet(RequestContext<I, O> requestContext) {
protected <I, O> HttpRequest.Builder createRequestBuilder(RequestContext<I, O> requestContext) {
var requestBuilder = HttpRequest.newBuilder()
.uri(this.baseUrl.resolve(resolvePath(requestContext.getUri())))
.header("Accept", "application/json");
.header("Accept", "application/json")
.timeout(this.readTimeout);

if (Utils.isNotNullOrBlank(this.apiKey)) {
requestBuilder.header(API_KEY_HEADER_NAME, this.apiKey);
Expand Down Expand Up @@ -382,6 +397,8 @@ public abstract static class DoclingServeClientBuilder<C extends DoclingServeCli
private boolean logResponses = false;
private boolean prettyPrintJson = false;
private @Nullable String apiKey;
private Duration connectTimeout = Duration.ofSeconds(5);
private Duration readTimeout = Duration.ofSeconds(30);
private Duration asyncPollInterval = Duration.ofSeconds(2);
private Duration asyncTimeout = Duration.ofMinutes(5);

Expand Down Expand Up @@ -467,6 +484,18 @@ public B prettyPrint(boolean prettyPrint) {
return (B) this;
}

@Override
public B connectTimeout(Duration connectTimeout) {
this.connectTimeout = connectTimeout;
return (B) this;
}

@Override
public B readTimeout(Duration readTimeout) {
this.readTimeout = readTimeout;
return (B) this;
}

/**
* Sets the polling interval for async operations.
*
Expand All @@ -475,14 +504,9 @@ public B prettyPrint(boolean prettyPrint) {
*
* @param asyncPollInterval the polling interval (must not be null or negative)
* @return this builder instance for method chaining
* @throws IllegalArgumentException if asyncPollInterval is null or negative
*/
@Override
public B asyncPollInterval(Duration asyncPollInterval) {
if (asyncPollInterval == null || asyncPollInterval.isNegative() || asyncPollInterval.isZero()) {
throw new IllegalArgumentException("asyncPollInterval must be a positive duration");
}

this.asyncPollInterval = asyncPollInterval;
return (B) this;
}
Expand All @@ -495,13 +519,9 @@ public B asyncPollInterval(Duration asyncPollInterval) {
*
* @param asyncTimeout the timeout duration (must not be null or negative)
* @return this builder instance for method chaining
* @throws IllegalArgumentException if asyncTimeout is null or negative
*/
@Override
public B asyncTimeout(Duration asyncTimeout) {
if (asyncTimeout == null || asyncTimeout.isNegative() || asyncTimeout.isZero()) {
throw new IllegalArgumentException("asyncTimeout must be a positive duration");
}
this.asyncTimeout = asyncTimeout;
return (B) this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ void pathPartFromBaseUrl() {
.logResponses()
.prettyPrint()
.baseUrl(baseUrl)
.connectTimeout(Duration.ofSeconds(10))
.readTimeout(Duration.ofSeconds(45))
.build();

assertThat(client.health())
Expand Down