proto: add more high-level API docs to Connection, closes #924 (#926)

This commit is contained in:
Ximin Luo
2020-12-02 19:30:09 +00:00
committed by GitHub
parent 6d84453037
commit cfe6570a66
2 changed files with 45 additions and 2 deletions
+44 -2
View File
@@ -54,10 +54,44 @@ use timer::{Timer, TimerTable};
/// Protocol state and logic for a single QUIC connection
///
/// Objects of this type receive `ConnectionEvent`s and emit `EndpointEvents` and application
/// `Event`s to make progress. To handle timeouts, a `Connection` returns timer updates and
/// Objects of this type receive [`ConnectionEvent`]s and emit [`EndpointEvents`] and application
/// [`Event`]s to make progress. To handle timeouts, a `Connection` returns timer updates and
/// expects timeouts through various methods. A number of simple getter methods are exposed
/// to allow callers to inspect some of the connection state.
///
/// `Connection` has roughly 4 types of methods:
///
/// - A. Simple getters, taking `&self`
/// - B. Handlers for incoming events from the network or system, named `handle_*`.
/// - C. State machine mutators, for incoming commands from the application. For
/// convenience we refer to this as "performing I/O" below, however as per
/// the design of this library none of the functions actually perform
/// system-level I/O. For example, [`read`](self::read) and [`write`](self::write),
/// but also things like [`reset`](self::reset).
/// - D. Polling functions for outgoing events or actions for the caller to
/// take, named `poll_*`.
///
/// The simplest way to use this API correctly is to call (B) and (C) whenever
/// appropriate, then after each of those calls, as soon as feasible call all
/// polling methods (D) and deal with their outputs appropriately, e.g. by
/// passing it to the application or by making a system-level I/O call. You
/// should call the polling functions in this order:
///
/// 1. [`poll_transmit`](self::poll_transmit)
/// 2. [`poll_timeout`](self::poll_timeout)
/// 3. [`poll_endpoint_events`](self::poll_endpoint_events)
/// 4. [`poll`](self::poll)
///
/// Currently the only actual dependency is from (2) to (1), however additional
/// dependencies may be added in future, so the above order is recommended.
///
/// (A) may be called whenever desired.
///
/// Care should be made to ensure that the input events represent monotonically
/// increasing time. Specifically, calling [`handle_timeout`](self::handle_timeout)
/// with events of the same [`Instant`] may be interleaved in any order with a
/// call to [`handle_event`](self::handle_event) at that same instant; however
/// events or timeouts with different instants must not be interleaved.
pub struct Connection<S>
where
S: crypto::Session,
@@ -280,6 +314,7 @@ where
/// - a call was made to `handle_event`
/// - a call to `poll_transmit` returned `Some`
/// - a call was made to `handle_timeout`
#[must_use]
pub fn poll_timeout(&mut self) -> Option<Instant> {
self.timers.next_timeout()
}
@@ -289,6 +324,7 @@ where
/// Connections should be polled for events after:
/// - a call was made to `handle_event`
/// - a call was made to `handle_timeout`
#[must_use]
pub fn poll(&mut self) -> Option<Event> {
if let Some(event) = self.streams.poll() {
return Some(Event::Stream(event));
@@ -302,6 +338,7 @@ where
}
/// Return endpoint-facing events
#[must_use]
pub fn poll_endpoint_events(&mut self) -> Option<EndpointEvent> {
self.endpoint_events.pop_front().map(EndpointEvent)
}
@@ -312,6 +349,7 @@ where
/// - the application performed some I/O on the connection
/// - a call was made to `handle_event`
/// - a call was made to `handle_timeout`
#[must_use]
pub fn poll_transmit(&mut self, now: Instant) -> Option<Transmit> {
if self.anti_amplification_blocked() {
trace!("blocked by anti-amplification");
@@ -728,6 +766,10 @@ where
/// Executes protocol logic, potentially preparing signals (including application `Event`s,
/// `EndpointEvent`s and outgoing datagrams) that should be extracted through the relevant
/// methods.
///
/// It is most efficient to call this immediately after the system clock reaches the latest
/// `Instant` that was output by `poll_timeout`; however spurious extra calls will simply
/// no-op and therefore are safe.
pub fn handle_timeout(&mut self, now: Instant) {
for &timer in &Timer::VALUES {
if !self.timers.is_expired(timer, now) {
+1
View File
@@ -97,6 +97,7 @@ where
}
/// Get the next packet to transmit
#[must_use]
pub fn poll_transmit(&mut self) -> Option<Transmit> {
self.transmits.pop_front()
}