floor the electrum batch page size at one when halving it after a timeout

This commit is contained in:
Craig Raw
2026-09-14 13:59:10 +02:00
parent f6235bbea9
commit cc3257a5ea
2 changed files with 37 additions and 4 deletions
@@ -229,11 +229,11 @@ public class PagedBatchRequestBuilder<K, V> extends AbstractBuilder {
pageSize = DEFAULT_PAGE_SIZE;
}
//Halve the page size if there have been timeouts
//Halve the page size if there have been timeouts, but never below one request, which is as small as a page can be
if(transport instanceof TimeoutCounter timeoutCounter) {
int timeouts = timeoutCounter.getTimeoutCount();
if(timeouts > 0) {
return pageSize / 2;
return Math.max(1, pageSize / 2);
}
}
@@ -130,10 +130,29 @@ public class PagedBatchRequestBuilderTest {
assertEquals(2, transport.requests.size(), "pageSize set before keysType and returnType must be carried onto the copies they return");
}
@SuppressWarnings("unchecked")
/**
* A timeout halves the page size, and a page size of one halved to zero, which Lists.partition rejects - failing every paged request for the rest of
* the session on a configured maximum of one. One request is as small as a page can be, and a larger size is still halved.
*/
@Test
public void pageSizeHalvedAfterATimeoutIsNeverBelowOne() throws Exception {
FakeBatchTransport transport = new TimingOutBatchTransport();
builder(transport, 1).executeTolerant(1, "ERROR", e -> {});
assertEquals(6, transport.requests.size());
FakeBatchTransport halved = new TimingOutBatchTransport();
builder(halved, 4).executeTolerant(1, "ERROR", e -> {});
assertEquals(3, halved.requests.size());
}
private PagedBatchRequestBuilder<String, String> builder(Transport transport) {
return builder(transport, 2);
}
@SuppressWarnings("unchecked")
private PagedBatchRequestBuilder<String, String> builder(Transport transport, int pageSize) {
PagedBatchRequestBuilder<String, String> batchRequest =
(PagedBatchRequestBuilder<String, String>)PagedBatchRequestBuilder.create(transport, new AtomicLong()).keysType(String.class).returnType(String.class).pageSize(2);
(PagedBatchRequestBuilder<String, String>)PagedBatchRequestBuilder.create(transport, new AtomicLong()).keysType(String.class).returnType(String.class).pageSize(pageSize);
for(String id : List.of("a", "b", "c", "d", "e", "f")) {
batchRequest.add(id, "test.method", id);
}
@@ -182,4 +201,18 @@ public class PagedBatchRequestBuilderTest {
return MAPPER.writeValueAsString(responses);
}
}
/**
* A transport that has seen a timeout, which is what the page size is halved on.
*/
private static class TimingOutBatchTransport extends FakeBatchTransport implements TimeoutCounter {
TimingOutBatchTransport() {
super(Set.of(), 0);
}
@Override
public int getTimeoutCount() {
return 1;
}
}
}