Asynchronous operations
Most of the operations that you can perform on a UAV, a docking station or any other model object handled by the server can potentially be long-running, meaning that there is a significant time interval between the time the server receives your initial request and the time the targeted object (typically a UAV) finishes processing the message. This is especially true if there is a slower or unreliable link between the server and the UAV and the message requires several retransmissions from the server to the UAV to go through. Sometimes the message triggers an even longer operation on the UAV.
To keep the server responsive, potentially long-running operations are handled asynchronously, meaning that the server will acknowledge the receipt of the message with a response as early as possible, and performs the actual operation in the background. The response that the server sends back contains a unique receipt identifier, which can be used in subsequent requests to poll the status and progress of the operation. The real result of the operation will come in a notification sent by the server later on. The notification always contains the receipt identifier to help the client associate its own requests with the result from the server.
Format of an asynchronous response
In the general case, the response body of a fictional request of SOME-REQ
that
can potentially be handled asynchronously by the server looks like this:
{
"type": "SOME-REQ",
"result": 1234,
"error": "Not enough beer left in the fridge",
"receipt": "0badcafedeadbeef"
}
Note that the type of the response may or may not be the same as the type of the request. By default, it is assumed that the expected response type is the same as the type of the request; if they are different, it will always be documented explicitly. The behaviour of the response body will always be the same, though, so it will likely be omitted in the specification and you should simply refer to this section instead.
Besides type
, exactly one additional top-level key will be present in the
response. If the server decided to execute the operation immediately, it
returns the result of the operation associated to the result
key. If the
server decided to execute the operation immediately and it already knows that
it failed, it returns the error message associated to the error
key. If the
server started the operation asynchronously, it returns the receipt identifier
instead in the receipt
key. It is a protocol error to respond with an
object that contains more than one of the keys above.
If the server decided to handle the operation asynchronously, it will deliver
the result of the operation in an ASYNC-RESP
notification. The notification will contain an id
key that has the same value
as the receipt
in the initial response.
When the operation is in progress on the server, the server MAY send notifications
of type ASYNC-ST to inform the client about
the status of the operation. The notification contains a progress
object
with a progress value expressed as a percentage as well as a human-readable
message that can be shown on the client side.
For long-running operations that require additional input from the user as
the operation progresses, the server MAY suspend the execution of the operation
while it is waiting for input. In case of a suspension, the server MUST send
a notification of type ASYNC-ST with its
suspended
key set to true
to inform the client that additional input is
needed. The client MUST send a message of type
ASYNC-RESUME with the information
requested by the server if the client wishes to proceed with the operation,
or a message of type ASYNC-CANCEL
if the client is no longer interested in the result of the operation. Suspended
operations remain in suspended state on the server until one of the following
events happen:
-
The client cancels the operation with ASYNC-CANCEL
-
The client resumes the operation with ASYNC-RESUME
-
The client disconnects without responding
In some cases, the server may also decide to abandon an asynchronous operation
if it seems to take too long (which usually indicates a communication error
between the server and the target, typically a UAV). In such cases, the server
will deliver an ASYNC-TIMEOUT notification
instead, with the receipt
values of the operations that timed out in the
ids
key of the notification. Note that one ASYNC-TIMEOUT
message may deliver
a timeout notification for multiple async operations.
Multi-object asynchronous responses
Some messages (e.g., UAV-LAND) can target multiple objects at the same time. In this case, the response of the server will look like this:
{
"type": "SOME-RESP",
"result": {
"id1": 1234,
"id2": 2345
},
"error": {
"id3": "Not enough beer left in the fridge"
},
"receipt": {
"id4": "0badcafedeadbeef"
}
}
In other words, the result
, error
and receipt
keys will be mappings from
the targeted object IDs (e.g., UAV IDs) and the associated values will be the
results, error messages and receipts. Each ID sent in the original request
MUST appear in exactly one of the result
, error
and receipt
mappings.