From 5eac3385174ddb3ed3a937e697917f565cff9416 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Fri, 22 Sep 2023 18:29:45 +0200 Subject: [PATCH 1/6] CoapRequestFuture - Added new method `cancel()` (WIP) --- source/doap/client/request.d | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/doap/client/request.d b/source/doap/client/request.d index ba27780..fa0f303 100644 --- a/source/doap/client/request.d +++ b/source/doap/client/request.d @@ -288,6 +288,16 @@ public class CoapRequestFuture // Set the received response this.response = response; + // TODO: Set state as DONE + + // Wake up the sleepers + this.condition.notify(); + } + + package void cancel() + { + // TODO: Set state as cancelled + // Wake up the sleepers this.condition.notify(); } From ae0161860ab78e379edbe97a517cfeffc2be3023 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Fri, 22 Sep 2023 18:39:49 +0200 Subject: [PATCH 2/6] CoapRequestFuture - Added `RequestState` enum - State if `CREATED` on construction - Calling `receiveWake(CoapPacket)` now sets the state to `COMPLETED` - Calling `cancel()` now sets the state to `CANCELLED` --- source/doap/client/request.d | 42 ++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/source/doap/client/request.d b/source/doap/client/request.d index 614130c..4e7fc87 100644 --- a/source/doap/client/request.d +++ b/source/doap/client/request.d @@ -229,6 +229,14 @@ package class CoapRequestBuilder import core.sync.mutex : Mutex; import core.sync.condition : Condition; + +private enum RequestState +{ + CREATED, + COMPLETED, + CANCELLED +} + /** * This is returned to the user when he * does a finalizing call on a `CoapRequestBuilder` @@ -249,7 +257,12 @@ public class CoapRequestFuture * This is filled in by the * messaging layer. */ - private CoapPacket response; + private CoapPacket response; // TODO: Volatility? + + /** + * State of the future + */ + private RequestState state; // TODO: Volatility? /** * Mutex (for the condition to use) @@ -270,6 +283,7 @@ public class CoapRequestFuture */ package this() { + this.state = RequestState.CREATED; this.mutex = new Mutex(); this.condition = new Condition(mutex); } @@ -288,15 +302,22 @@ public class CoapRequestFuture // Set the received response this.response = response; - // TODO: Set state as DONE + // Set completion state + this.state = RequestState.COMPLETED; // Wake up the sleepers this.condition.notify(); } + /** + * Cancels this future such that + * all calls to `get()` will + * unblock and throw an exception + */ package void cancel() { - // TODO: Set state as cancelled + // Set cancelled state + this.state = RequestState.CANCELLED; // Wake up the sleepers this.condition.notifyAll(); @@ -306,6 +327,8 @@ public class CoapRequestFuture * Blocks until the response is received * * Returns: the response as a `CoapPacket` + * Throws: + * CoapException on cancelled request */ public CoapPacket get() { @@ -319,7 +342,18 @@ public class CoapRequestFuture // Upon waking up release lock this.mutex.unlock(); - return this.response; + // If successfully completed + if(this.state == RequestState.COMPLETED) + { + return this.response; + } + // On error + else + { + throw new CoapException("Request future cancelled"); + } + + } } \ No newline at end of file From 7a30195d1081da35b6d7690ecdfec48e742d26fa Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Fri, 22 Sep 2023 18:40:13 +0200 Subject: [PATCH 3/6] CoapRequestFuture - Fixed `receiveWake(CoapPacket response)` to use `notifyAll()` --- source/doap/client/request.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/doap/client/request.d b/source/doap/client/request.d index 4e7fc87..b7dc6fe 100644 --- a/source/doap/client/request.d +++ b/source/doap/client/request.d @@ -306,7 +306,7 @@ public class CoapRequestFuture this.state = RequestState.COMPLETED; // Wake up the sleepers - this.condition.notify(); + this.condition.notifyAll(); } /** From d659c2348bdcabbef399938dab0dc0fbb7c3a5b5 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Fri, 22 Sep 2023 19:06:06 +0200 Subject: [PATCH 4/6] CoapClient - When `close()` is called we will unblock all active `get()` calls to futures --- source/doap/client/client.d | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source/doap/client/client.d b/source/doap/client/client.d index 3e83367..a38ffe7 100644 --- a/source/doap/client/client.d +++ b/source/doap/client/client.d @@ -111,8 +111,13 @@ public class CoapClient // Shutdown the messaging layer this.messaging.close(); - // TODO: We must wake up other sleeprs with an error - // (somehow, pass it in, flag set) + // Cancel all active request futures + this.requestsLock.lock(); + foreach(CoapRequest curReq; outgoingRequests) + { + curReq.future.cancel(); + } + this.requestsLock.unlock(); } /** From 2b2641f479aa068b78319047fac6a09da56f81f0 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Fri, 22 Sep 2023 19:54:11 +0200 Subject: [PATCH 5/6] Package - Make `RequestState` available CoapRequestFuture - Made `RequestState` public - Documented it --- source/doap/client/package.d | 2 +- source/doap/client/request.d | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/source/doap/client/package.d b/source/doap/client/package.d index 85e0e58..40a1ba2 100644 --- a/source/doap/client/package.d +++ b/source/doap/client/package.d @@ -1,4 +1,4 @@ module doap.client; public import doap.client.client : CoapClient; -public import doap.client.request : CoapRequestBuilder, CoapRequestFuture; \ No newline at end of file +public import doap.client.request : CoapRequestBuilder, CoapRequestFuture, RequestState; \ No newline at end of file diff --git a/source/doap/client/request.d b/source/doap/client/request.d index 26c4fca..6aa323d 100644 --- a/source/doap/client/request.d +++ b/source/doap/client/request.d @@ -258,10 +258,25 @@ import core.sync.mutex : Mutex; import core.sync.condition : Condition; -private enum RequestState +/** + * The state of a `CoapRequestFuture` + */ +public enum RequestState { + /** + * The future has been created + */ CREATED, + + /** + * The future has completed + * successfully + */ COMPLETED, + + /** + * The future was cancelled + */ CANCELLED } From 094d59feb11fce535bd581d1a36b063ccf6c1e83 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Fri, 22 Sep 2023 19:55:56 +0200 Subject: [PATCH 6/6] CoapRequestFuture - Added `getState()` - Cleaned up whitespace --- source/doap/client/request.d | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/source/doap/client/request.d b/source/doap/client/request.d index 6aa323d..8e05439 100644 --- a/source/doap/client/request.d +++ b/source/doap/client/request.d @@ -394,9 +394,16 @@ public class CoapRequestFuture else { throw new CoapException("Request future cancelled"); - } - - + } } + /** + * Returns the state of this future + * + * Returns: the state + */ + public RequestState getState() + { + return this.state; + } } \ No newline at end of file