pub struct RequestIdAllocator {
role: Role,
next_id: u64,
max_id: u64,
peer_next_id: u64,
peer_skipped: BTreeSet<u64>,
}Expand description
Allocates this endpoint’s request IDs and checks the parity of the peer’s.
Draft-16 Section 9.1: “The client’s Request ID starts at 0 and are even and the server’s Request ID starts at 1 and are odd. The Request ID increments by 2 with each FETCH, SUBSCRIBE, REQUEST_UPDATE, SUBSCRIBE_NAMESPACE, PUBLISH, PUBLISH_NAMESPACE or TRACK_STATUS request.” The step of two is what keeps the two endpoints’ ID spaces disjoint, so it is not a spacing convention an implementation may tighten: one that steps by one starts issuing the IDs reserved for its peer on its second request, and the same section makes that a session close with INVALID_REQUEST_ID.
The ceiling is exclusive. Section 9.5 describes the MAX_REQUEST_ID message’s Max Request ID field as “The new Maximum Request ID for the session plus 1”, and closes the session with TOO_MANY_REQUESTS on a request ID “equal to or larger than this”. Section 9.3.1.3 gives the setup parameter of the same name a default of 0 and reads that as “the peer MUST NOT send requests”, which only holds if a ceiling of 0 forbids the ID 0 as well.
Fields§
§role: Role§next_id: u64§max_id: u64§peer_next_id: u64§peer_skipped: BTreeSet<u64>Implementations§
Source§impl RequestIdAllocator
impl RequestIdAllocator
Sourcepub fn new(role: Role) -> Self
pub fn new(role: Role) -> Self
Create an allocator for the given role, starting at ID 0 or 1 with a ceiling of 0 - blocked until the peer raises it.
Sourcepub fn allocate(&mut self) -> Result<VarInt, RequestIdError>
pub fn allocate(&mut self) -> Result<VarInt, RequestIdError>
Allocate the next request ID.
§Errors
RequestIdError::Blocked when the next ID would reach the ceiling.
Sourcepub fn update_max(&mut self, new_max: u64) -> Result<(), RequestIdError>
pub fn update_max(&mut self, new_max: u64) -> Result<(), RequestIdError>
Update the maximum allowed request ID (can only increase).
§Errors
RequestIdError::Decreased if the new value is not strictly greater
than the current one, which Section 9.5 calls a protocol
violation.
Sourcepub fn validate_peer_id(&self, id: u64) -> Result<(), RequestIdError>
pub fn validate_peer_id(&self, id: u64) -> Result<(), RequestIdError>
Check the parity of a request ID the peer put on the wire.
The parity checked here is the peer’s, the opposite of this allocator’s own, so a client accepts only odd IDs.
This deliberately does not check the ID against a ceiling. The ceiling
that applies to a peer’s request ID is the MAX_REQUEST_ID this
endpoint advertised, which the allocator does not hold - max_id here
is the budget the peer granted us, a different number that may be
larger or smaller. The endpoint owns that check.
Parity is the half that needs no history. The duplicate half is
Self::record_peer_id, which does.
§Errors
RequestIdError::WrongParity carrying the ID and the peer’s
role, so the message names the endpoint that broke the rule rather than
the one that caught it.
Sourcepub fn is_blocked(&self) -> bool
pub fn is_blocked(&self) -> bool
Whether the next allocation would reach the ceiling.
A ceiling of 0 needs no special case: the client’s first ID is 0 and the server’s is 1, and neither is below 0.
Sourcepub fn peer_next_id(&self) -> u64
pub fn peer_next_id(&self) -> u64
The ID after the highest one the peer has used: its first ID until it sends a request, then the highest seen plus 2.
Sourcepub fn record_peer_id(&mut self, id: u64) -> Result<(), RequestIdError>
pub fn record_peer_id(&mut self, id: u64) -> Result<(), RequestIdError>
Take the Request ID of a new request the peer sent, refusing one it has already used.
The sequence is not enforced. Draft-16 opens SUBSCRIBE_NAMESPACE on its own stream, so requests can arrive out of order across streams; the editors’ guidance for draft-16 (moq-wg/moq-transport#1459) is to check parity, the ceiling and duplicates only. IDs jumped over are remembered as unused, up to a fixed number of the highest.
Only a new request is passed here. A message that names a request already open reuses its ID on purpose.
§Errors
RequestIdError::WrongParity for an ID from this endpoint’s half,
RequestIdError::Duplicate for one already used or no longer
remembered as skipped.