From b8bbd1b015d59523cf2054a6ad42be11dedc8652 Mon Sep 17 00:00:00 2001 From: Ben Culkin Date: Sun, 25 Jun 2023 16:30:36 -0400 Subject: Add timeout support Add support for timeouts to Terminal, so you can say you only want to wait so long for a given reply --- .../main/java/bjc/utils/cli/StreamTerminal.java | 27 +++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'base/src/main/java/bjc/utils/cli/StreamTerminal.java') diff --git a/base/src/main/java/bjc/utils/cli/StreamTerminal.java b/base/src/main/java/bjc/utils/cli/StreamTerminal.java index 69be8d7..87370f8 100644 --- a/base/src/main/java/bjc/utils/cli/StreamTerminal.java +++ b/base/src/main/java/bjc/utils/cli/StreamTerminal.java @@ -7,6 +7,8 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.locks.*; +import bjc.data.Either; + /** * Implementation of {@link Terminal} using {@link Reader} and {@link Writer} * @@ -149,6 +151,24 @@ public class StreamTerminal implements Terminal, Runnable { return pendingReplies.get(id); } } + + @Override + public Optional awaitReply(long id, TimeUnit unit, long delay) throws InterruptedException { + if (pendingReplies.containsKey(id)) + return Optional.of(pendingReplies.get(id)); + while (true) { + replyLock.lock(); + boolean stat = replyCondition.await(delay, unit); + replyLock.unlock(); + + // If we timed out, say so + if (stat == false) return Optional.empty(); + // Explanation: Since the reply map is add-only, the lock isn't actually + // protecting anything. We just want to wait until a response is received. + if (pendingReplies.containsKey(id)) + return Optional.of(pendingReplies.get(id)); + } + } @Override public Optional checkReply(long id) { @@ -160,5 +180,10 @@ public class StreamTerminal implements Terminal, Runnable { return awaitReply(submitRequest(req)); } - // TODO add variants of the two blocking methods above with timeout support + @Override + public Either submitRequestSync(String req, TimeUnit unit, long delay) throws InterruptedException { + long id = submitRequest(req); + Optional rep = awaitReply(id, unit, delay); + return rep.isEmpty() ? Either.right(id) : Either.left(rep.get()); + } } \ No newline at end of file -- cgit v1.2.3