Merge branch 'master' into feature/timeoutable_gets

This commit is contained in:
Tristan B. Velloza Kildaire 2023-09-25 13:47:34 +02:00
commit 2e499d267f
4 changed files with 95 additions and 5 deletions

View File

@ -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();
}
/**

View File

@ -1,4 +1,4 @@
module doap.client;
public import doap.client.client : CoapClient;
public import doap.client.request : CoapRequestBuilder, CoapRequestFuture;
public import doap.client.request : CoapRequestBuilder, CoapRequestFuture, RequestState;

View File

@ -257,6 +257,29 @@ package class CoapRequestBuilder
import core.sync.mutex : Mutex;
import core.sync.condition : Condition;
/**
* 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
}
/**
* This is returned to the user when he
* does a finalizing call on a `CoapRequestBuilder`
@ -277,7 +300,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)
@ -298,6 +326,7 @@ public class CoapRequestFuture
*/
package this()
{
this.state = RequestState.CREATED;
this.mutex = new Mutex();
this.condition = new Condition(mutex);
}
@ -316,6 +345,23 @@ public class CoapRequestFuture
// Set the received response
this.response = response;
// Set completion state
this.state = RequestState.COMPLETED;
// Wake up the sleepers
this.condition.notifyAll();
}
/**
* Cancels this future such that
* all calls to `get()` will
* unblock and throw an exception
*/
package void cancel()
{
// Set cancelled state
this.state = RequestState.CANCELLED;
// Wake up the sleepers
this.condition.notifyAll();
}
@ -324,6 +370,8 @@ public class CoapRequestFuture
* Blocks until the response is received
*
* Returns: the response as a `CoapPacket`
* Throws:
* CoapException on cancelled request
*/
public CoapPacket get()
{
@ -337,7 +385,16 @@ 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");
}
}
public CoapPacket get(Duration timeout)
@ -361,4 +418,14 @@ public class CoapRequestFuture
throw new CoapException("Timed out whilst waiting");
}
}
/**
* Returns the state of this future
*
* Returns: the state
*/
public RequestState getState()
{
return this.state;
}
}

View File

@ -89,6 +89,10 @@ public class CoapPacket
}
// FIXME: Add options encoding
foreach(CoapOption option; orderOptions())
{
encoded ~= encodeOption(option);
}
// Set the payload marker
encoded ~= PAYLOAD_MARKER;
@ -99,6 +103,20 @@ public class CoapPacket
return encoded;
}
// TODO: Make public in the future
private static ubyte[] encodeOption(CoapOption option)
{
// TODO: Implement this
return [];
}
private CoapOption[] orderOptions()
{
// TODO: Implement ordering here
return this.options;
}
public void setType(MessageType type)
{
this.type = type;