Asynchronous Commands¶
Methods whose names end with Async
are asynchronous commands. These commands are
sent to the server as a request and queued for processing. Asynchronous methods return Request Structure. Use getRequestStatus()
and getRequestResult()
to monitor the
status of a request.
RequestId¶
All asynchronous methods from the JetStream API return a Request Structure containing requestId
. Because of their
asynchronous nature, such methods cannot return any meaningful data. You must use the returned structure or the requestId
to
monitor the status of the request, and to retrieve its result.
>>> request = api.send.setSendRateAsync(...)
{'requestId': 17}
>>> requestId = request['requestId']
17
Using A RequestId¶
The JetStream API provides two methods that operate on requestId
:
getRequestStatus()
will return the status of the request, indicating whether it is still being processed by the server. This method returns immediately.
getRequestResult()
will wait until the request is completed and return its result. This method blocks until the result is available.
These two methods are available from ServerInterface
class.
- Example:
>>> status = api.server.getRequestStatus(requestId) {'requestId': 17, 'processing': False} >>> result = api.server.getRequestResult(requestId) {'blockSize': 256, 'blocksAcked': 0, 'blocksSent': 0, 'bytesRecv': 0, 'bytesSent': 0, 'destinationId': 'receiver01:8886', 'endTime': None, 'errorMessage': '', 'packetsRecv': 0, 'packetsSent': 0, 'processing': True, 'queueTime': None, 'requestTime': 1477934856594315, 'snapshotTime': 1477934856594318, 'startTime': None, 'status': 'pending', 'totalBlocks': 3354311, 'totalBytes': 858703405, 'transferId': 7}
It is not required that you monitor a request, nor that you retrieve its result. The request will be fulfilled without your intervention.
Expiry Of A RequestId¶
In order to allow you to retrieve the results from an asynchronous method, it is necessary that the
server maintain a record of its asynchronous requests, as well as a copy of the result it produced. It is not
feasible for the server to maintain this association indefinitely, as the server would eventually
run out of resources. For this reason, asynchronous requests will eventually expire. After it expires,
its result will no longer be available, and calls to getRequestStatus and getRequestResult using
the expired requestId
will fail. A requestId
is never reused.
- Example:
>>> status = api.server.getRequestStatus(requestId) {'requestId': 17, 'processing': False}(time passes…)
>>> status = api.server.getRequestStatus(requestId) # CommandException: No request with specified ID.
Asynchronous Requests vs Ongoing Tasks¶
The commands createManifest()
and createTransfer()
are unique in the fact that they initiate a task on the server which may not be complete at the point where the command returns. The server handles these operations differently than others, and for this reason these methods do not use the “Async
” naming scheme. Clients using the JetStream API will need to be aware of this, and be prepared to handle manifest and transfer results differently than other results.
Commands such as setSendRateAsync()
and suspendTransferAsync()
are asynchronous requests. They do not return a result. Instead, they return a Request Structure which must be submitted to the API to retrieve the result.
- Examples:
>>> requestId = api.send.setSendRateAsync(...) {'requestId': 3} >>> result = api.server.getRequestResult(requestId) {'sendRate': 12345.0}>>> requestId = api.send.suspendTransferAsync(...) {'requestId': 13} >>> result = api.server.getRequestResult(requestId) {'transferId': '00f74049d7201b46020000000000000d'}
In the examples above, setSendRateAsync
and suspendTransferAsync
each add a request to the server’s request queue. When getRequestResult()
is called the API will block until the server has processed the request associated with the requestId
, and will return the command’s result.
To compare, createManifest()
and createTransfer()
are synchronous, and each returns a result. The createManifest()
command returns a Manifest Structure, and the createTransfer()
command returns a Transfer Structure.
- Examples:
>>> manifest = api.send.createManifest(...) {'errorMessage': None, 'manifestId': '00f74049d7201b460100000000000000', 'processing': True, 'status': 'pending', 'totalFiles': None, 'totalSize': None}>>> transfer = api.send.createTransfer(...) {'manifestId': '00f74049d7201b460100000000000008', 'packetsRecv': 0, 'packetsSent': 0, 'priority': 100, 'processing': True, 'queueTime': None, 'requestTime': 1494285094171160, 'snapshotTime': 1494285094171177, 'startTime': None, 'status': 'pending', 'transferId': '00f74049d7201b460200000000000009'}
However, these structures both describe an ongoing task. The distinction lies in how manifests and transfers are managed by the server. For clients of the API, what’s important is that waiting for the completion of a manifest or transfer is performed via waitForManifest()
and waitForTransfer()
, respectively.
- Examples:
>>> manifest = api.send.waitForManifest(manifest) {'errorMessage': None, 'manifestId': '00f74049d7201b460100000000000000', 'processing': False, 'status': 'complete', 'totalFiles': 617, 'totalSize': 11963203587}>>> transfer = api.send.waitForTransfer(transfer) {'manifestId': '00f74049d7201b460100000000000008', 'packetsRecv': 12, 'packetsSent': 20682, 'priority': 100, 'processing': False, 'queueTime': 1494285094171217, 'requestTime': 1494285094171160, 'snapshotTime': 1494285107174540, 'startTime': 1494285094171421, 'status': 'complete', 'transferId': '00f74049d7201b460200000000000009'}