Skip to content
Closed
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

1. [#306](https://github.com/InfluxCommunity/influxdb3-java/pull/306): Improve closing of Arrow `FlightStream`.

### Bug Fixes

1. [#301](https://github.com/InfluxCommunity/influxdb3-java/issues/301): Fix gRPC deadline reuse issue causing "deadline exceeded" errors when `QueryOptions` instances are reused across multiple queries.

## 1.5.0 [2025-10-22]

### Features
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -398,13 +398,6 @@ private Stream<VectorSchemaRoot> queryData(@Nonnull final String query,
Arguments.checkNotNull(parameters, "parameters");
Arguments.checkNotNull(options, "options");

if (options.grpcCallOptions().getDeadline() == null && config.getQueryTimeout() != null) {
options.setGrpcCallOptions(new GrpcCallOptions.Builder()
.fromGrpcCallOptions(options.grpcCallOptions())
.withDeadline(Deadline.after(config.getQueryTimeout().toMillis(), TimeUnit.MILLISECONDS))
.build());
}

if (closed) {
throw new IllegalStateException("InfluxDBClient has been closed.");
}
Expand All @@ -421,7 +414,16 @@ private Stream<VectorSchemaRoot> queryData(@Nonnull final String query,
}
});

CallOption[] callOptions = options.grpcCallOptions().getCallOptions();
// Create a fresh deadline for this query if queryTimeout is configured and no explicit deadline is set
GrpcCallOptions grpcCallOptions = options.grpcCallOptions();
if (grpcCallOptions.getDeadline() == null && config.getQueryTimeout() != null) {
grpcCallOptions = new GrpcCallOptions.Builder()
.fromGrpcCallOptions(grpcCallOptions)
.withDeadline(Deadline.after(config.getQueryTimeout().toMillis(), TimeUnit.MILLISECONDS))
.build();
}

CallOption[] callOptions = grpcCallOptions.getCallOptions();

return flightSqlClient.execute(
query,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,25 @@ void testToString() {
+ "maxOutboundMessageSize=5000}";
assertEquals(expected, options.toString());
}

@Test
void testDeadlineIsNotZeroOrPast() throws InterruptedException {
// Create a deadline 5 seconds from now
Deadline deadline = Deadline.after(5000, TimeUnit.MILLISECONDS);
GrpcCallOptions options = new GrpcCallOptions.Builder()
.withDeadline(deadline)
.build();

// Verify the deadline is in the future
assertNotNull(options.getDeadline());
long timeRemaining = options.getDeadline().timeRemaining(TimeUnit.MILLISECONDS);
Assertions.assertTrue(timeRemaining > 0, "Deadline should be in the future");
Assertions.assertTrue(timeRemaining <= 5000, "Deadline should not exceed 5 seconds");

// Wait a bit and verify deadline is still valid but closer
TimeUnit.MILLISECONDS.sleep(100);
long timeRemainingAfter = options.getDeadline().timeRemaining(TimeUnit.MILLISECONDS);
Assertions.assertTrue(timeRemainingAfter > 0, "Deadline should still be in the future");
Assertions.assertTrue(timeRemainingAfter < timeRemaining, "Deadline should be closer to expiration");
}
}