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
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@
<com.squareup.okhttp3.version>4.12.0</com.squareup.okhttp3.version>
<info.picocli.version>4.7.7</info.picocli.version>
<org.apache.commons.math3.version>3.6.1</org.apache.commons.math3.version>
<org.apache.httpcomponents.client5.httpclient5.version>5.4.4</org.apache.httpcomponents.client5.httpclient5.version>
<org.apache.httpcomponents.client5.httpclient5.version>5.6.3</org.apache.httpcomponents.client5.httpclient5.version>
<commons-codec.version>1.21.0</commons-codec.version>
<org.apache.pdfbox.version>3.0.7</org.apache.pdfbox.version>
<org.mapstruct.version>1.5.3.Final</org.mapstruct.version>
Expand Down
7 changes: 2 additions & 5 deletions src/main/java/com/mindee/v2/MindeeClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,10 @@ private <TResponse extends CommonResponse> TResponse pollAndFetch(
JobResponse resp = initialJob;
int attempts = 0;
int max = pollingOptions.getMaxRetries();
double currentIntervalSec = pollingOptions.getIntervalSec();
double maxIntervalSec = pollingOptions.getMaxIntervalSec();
double backoffMultiplier = pollingOptions.getBackoffMultiplier();
long intervalMillis = (long) (pollingOptions.getIntervalSec() * 1000);

while (attempts < max) {
interruptibleSleep((long) (currentIntervalSec * 1000), pollingOptions);
interruptibleSleep(intervalMillis, pollingOptions);
Comment thread
sebastianMindee marked this conversation as resolved.
resp = getJob(initialJob.getJob().getId());

if (resp.getJob().getStatus().equals("Failed")) {
Expand All @@ -275,7 +273,6 @@ private <TResponse extends CommonResponse> TResponse pollAndFetch(
if (resp.getJob().getStatus().equals("Processed")) {
return getResult(responseClass, resp.getJob().getId());
}
currentIntervalSec = Math.min(currentIntervalSec * backoffMultiplier, maxIntervalSec);
attempts++;
}

Expand Down
28 changes: 1 addition & 27 deletions src/main/java/com/mindee/v2/clientoptions/PollingOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,6 @@
import lombok.Getter;

public class PollingOptions extends BasePollingOptions {

/**
* Multiplier applied to {@code intervalSec} after each poll attempt to implement
* exponential backoff. Must be ≥ 1.0. A value of 1.0 disables backoff.
*/
@Getter
private final Double backoffMultiplier;

/**
* Upper bound (in seconds) for the polling interval after backoff is applied.
* Must be ≥ {@code intervalSec}.
*/
@Getter
private final Double maxIntervalSec;

/**
* Optional cancellation signal. When it evaluates to {@code true}, polling is
* aborted with a {@link java.util.concurrent.CancellationException}. Also,
Expand All @@ -34,21 +19,10 @@ public PollingOptions(
Double initialDelaySec,
Double intervalSec,
Integer maxRetries,
Double backoffMultiplier,
Double maxIntervalSec,
BooleanSupplier cancelToken
) {
super(initialDelaySec, intervalSec, maxRetries, 3.0, 1.5, 100, 1.0, 1.0, 2);
this.backoffMultiplier = backoffMultiplier == null ? 1.5 : backoffMultiplier;
if (this.backoffMultiplier < 1.0) {
throw new IllegalArgumentException("Backoff multiplier must be ≥ 1.0");
}
this.maxIntervalSec = maxIntervalSec == null ? 60.0 : maxIntervalSec;
if (this.maxIntervalSec < this.getIntervalSec()) {
throw new IllegalArgumentException(
"Max interval must be ≥ interval (" + this.getIntervalSec() + ")"
);
}

this.cancelToken = cancelToken == null ? () -> false : cancelToken;
}
}
18 changes: 1 addition & 17 deletions src/test/java/com/mindee/v2/MindeeClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ void blankUrl_throws() {
}

@Nested
@DisplayName("polling with cancellation and backoff")
@DisplayName("polling with cancellation")
class Polling {
private JobResponse processing() throws JsonProcessingException {
String json = "{\"job\": {\"id\": \"dummy-id\", \"status\": \"Processing\"}}";
Expand Down Expand Up @@ -284,21 +284,5 @@ public JobResponse reqGetJobById(String jobId) {
assertTrue(jobCalls.get() >= 1, "at least one poll should occur before cancellation");
}

@Test
@DisplayName("interval grows with backoff up to maxIntervalSec")
void polling_backoff_caps() {
var options = PollingOptions
.builder()
.intervalSec(1.0)
.backoffMultiplier(2.0)
.maxIntervalSec(5.0)
.build();

double interval = options.getIntervalSec();
for (int i = 0; i < 10; i++) {
interval = Math.min(interval * options.getBackoffMultiplier(), options.getMaxIntervalSec());
}
assertEquals(5.0, interval);
}
}
}
26 changes: 0 additions & 26 deletions src/test/java/com/mindee/v2/clientoptions/PollingOptionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ void shouldSetDefaultValues() {
Assertions.assertEquals(3.0, pollingOptions.getInitialDelaySec());
Assertions.assertEquals(1.5, pollingOptions.getIntervalSec());
Assertions.assertEquals(100, pollingOptions.getMaxRetries());
Assertions.assertEquals(1.5, pollingOptions.getBackoffMultiplier());
Assertions.assertEquals(60.0, pollingOptions.getMaxIntervalSec());
Assertions.assertNotNull(pollingOptions.getCancelToken());
Assertions.assertFalse(pollingOptions.getCancelToken().getAsBoolean());
}
Expand All @@ -27,16 +25,12 @@ void shouldSetCustomValues() {
.initialDelaySec(4.0)
.intervalSec(2.5)
.maxRetries(50)
.backoffMultiplier(2.0)
.maxIntervalSec(30.0)
.cancelToken(cancelled::get)
.build();

Assertions.assertEquals(4.0, pollingOptions.getInitialDelaySec());
Assertions.assertEquals(2.5, pollingOptions.getIntervalSec());
Assertions.assertEquals(50, pollingOptions.getMaxRetries());
Assertions.assertEquals(2.0, pollingOptions.getBackoffMultiplier());
Assertions.assertEquals(30.0, pollingOptions.getMaxIntervalSec());

Assertions.assertFalse(pollingOptions.getCancelToken().getAsBoolean());
cancelled.set(true);
Expand All @@ -52,24 +46,4 @@ void shouldThrowWhenInitialDelayIsTooLow() {
);
Assertions.assertEquals("Initial delay must be ≥ 1.0", exception.getMessage());
}

@Test
void shouldThrowWhenBackoffMultiplierIsTooLow() {
IllegalArgumentException exception = Assertions
.assertThrows(
IllegalArgumentException.class,
() -> PollingOptions.builder().backoffMultiplier(0.9).build()
);
Assertions.assertEquals("Backoff multiplier must be ≥ 1.0", exception.getMessage());
}

@Test
void shouldThrowWhenMaxIntervalIsBelowInterval() {
IllegalArgumentException exception = Assertions
.assertThrows(
IllegalArgumentException.class,
() -> PollingOptions.builder().intervalSec(5.0).maxIntervalSec(2.0).build()
);
Assertions.assertTrue(exception.getMessage().startsWith("Max interval must be ≥ interval"));
}
}
Loading