Skip to content

Commit 565a49d

Browse files
committed
changed timeout approach to blocking
Signed-off-by: Alex Kehayov <aleks.kehayov@limechain.tech>
1 parent 297f835 commit 565a49d

File tree

2 files changed

+209
-166
lines changed

2 files changed

+209
-166
lines changed

hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/impl/streaming/BlockNodeConnection.java

Lines changed: 38 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,13 @@
3030
import java.util.List;
3131
import java.util.Objects;
3232
import java.util.Optional;
33+
import java.util.concurrent.ExecutionException;
3334
import java.util.concurrent.Flow;
35+
import java.util.concurrent.Future;
3436
import java.util.concurrent.ScheduledExecutorService;
3537
import java.util.concurrent.ScheduledFuture;
3638
import java.util.concurrent.TimeUnit;
39+
import java.util.concurrent.TimeoutException;
3740
import java.util.concurrent.atomic.AtomicBoolean;
3841
import java.util.concurrent.atomic.AtomicLong;
3942
import java.util.concurrent.atomic.AtomicReference;
@@ -683,30 +686,26 @@ public void sendRequest(@NonNull final PublishStreamRequest request) {
683686
}
684687
final long startMs = System.currentTimeMillis();
685688

686-
// Schedule timeout task to detect unresponsive block nodes
687-
final ScheduledFuture<?> timeoutTask = executorService.schedule(
688-
() -> {
689-
if (getConnectionState() == ConnectionState.ACTIVE) {
690-
logWithContext(
691-
logger,
692-
DEBUG,
693-
this,
694-
"Pipeline onNext() timed out after {}ms",
695-
pipelineOperationTimeout.toMillis());
696-
blockStreamMetrics.recordPipelineOperationTimeout();
697-
handleStreamFailure();
698-
}
699-
},
700-
pipelineOperationTimeout.toMillis(),
701-
TimeUnit.MILLISECONDS);
702-
689+
Future<?> future = executorService.submit(() -> pipeline.onNext(request));
703690
try {
704-
pipeline.onNext(request);
705-
} finally {
706-
// Cancel timeout if operation completes (successfully or not)
707-
if (!timeoutTask.isDone()) {
708-
timeoutTask.cancel(false);
691+
future.get(pipelineOperationTimeout.toMillis(), TimeUnit.MILLISECONDS);
692+
} catch (TimeoutException e) {
693+
future.cancel(true); // Cancel the task if it times out
694+
if (getConnectionState() == ConnectionState.ACTIVE) {
695+
logWithContext(
696+
logger,
697+
DEBUG,
698+
this,
699+
"Pipeline onNext() timed out after {}ms",
700+
pipelineOperationTimeout.toMillis());
701+
blockStreamMetrics.recordPipelineOperationTimeout();
702+
handleStreamFailure();
709703
}
704+
} catch (InterruptedException e) {
705+
Thread.currentThread().interrupt(); // Restore interrupt status
706+
throw new RuntimeException("Interrupted while waiting for pipeline.onNext()", e);
707+
} catch (ExecutionException e) {
708+
throw new RuntimeException("Error executing pipeline.onNext()", e.getCause());
710709
}
711710

712711
final long durationMs = System.currentTimeMillis() - startMs;
@@ -801,32 +800,26 @@ private void closePipeline(final boolean callOnComplete) {
801800
try {
802801
final ConnectionState state = getConnectionState();
803802
if (state == ConnectionState.CLOSING && callOnComplete) {
804-
// Schedule timeout task to detect unresponsive block nodes during close
805-
final ScheduledFuture<?> timeoutTask = executorService.schedule(
806-
() -> {
807-
logWithContext(
808-
logger,
809-
DEBUG,
810-
this,
811-
"Pipeline onComplete() timed out after {}ms",
812-
pipelineOperationTimeout.toMillis());
813-
blockStreamMetrics.recordPipelineOperationTimeout();
814-
// Connection is already closing, just log the timeout
815-
},
816-
pipelineOperationTimeout.toMillis(),
817-
TimeUnit.MILLISECONDS);
818-
803+
Future<?> future = executorService.submit(pipeline::onComplete);
819804
try {
820-
pipeline.onComplete();
805+
future.get(pipelineOperationTimeout.toMillis(), TimeUnit.MILLISECONDS);
821806
logWithContext(logger, DEBUG, this, "Request pipeline successfully closed.");
822-
} finally {
823-
// Cancel timeout if operation completes (successfully or not)
824-
if (!timeoutTask.isDone()) {
825-
timeoutTask.cancel(false);
826-
}
807+
} catch (TimeoutException e) {
808+
future.cancel(true); // Cancel the task if it times out
809+
logWithContext(
810+
logger,
811+
DEBUG,
812+
this,
813+
"Pipeline onComplete() timed out after {}ms",
814+
pipelineOperationTimeout.toMillis());
815+
blockStreamMetrics.recordPipelineOperationTimeout();
816+
// Connection is already closing, just log the timeout
817+
} catch (InterruptedException e) {
818+
Thread.currentThread().interrupt(); // Restore interrupt status
819+
logWithContext(logger, DEBUG, this, "Interrupted while waiting for pipeline.onComplete()");
820+
} catch (ExecutionException e) {
821+
logWithContext(logger, DEBUG, this, "Error executing pipeline.onComplete()", e.getCause());
827822
}
828-
829-
logWithContext(logger, DEBUG, this, "Request pipeline successfully closed.");
830823
}
831824
} catch (final Exception e) {
832825
logger.warn(formatLogMessage("Error while completing request pipeline.", this), e);

0 commit comments

Comments
 (0)