Add note about cookie tracking serialization.

This commit is contained in:
Sergio Benitez 2018-11-08 21:38:44 -08:00
parent 64ba2056ef
commit b16269a30e
1 changed files with 27 additions and 11 deletions

View File

@ -10,16 +10,17 @@ use error::LaunchError;
///
/// # Usage
///
/// A `Client` is constructed via the [`new`] or [`untracked`] methods from an
/// already constructed `Rocket` instance. Once a value of `Client` has been
/// constructed, the [`LocalRequest`] constructor methods ([`get`], [`put`],
/// [`post`], and so on) can be used to create a `LocalRequest` for dispatching.
/// A `Client` is constructed via the [`new()`] or [`untracked()`] methods from
/// an already constructed `Rocket` instance. Once a value of `Client` has been
/// constructed, the [`LocalRequest`] constructor methods ([`get()`], [`put()`],
/// [`post()`], and so on) can be used to create a `LocalRequest` for
/// dispatching.
///
/// See the [top-level documentation](::local) for more usage information.
///
/// ## Cookie Tracking
///
/// A `Client` constructed using [`new`] propagates cookie changes made by
/// A `Client` constructed using [`new()`] propagates cookie changes made by
/// responses to previously dispatched requests. In other words, if a previously
/// dispatched request resulted in a response that adds a cookie, any future
/// requests will contain that cookie. Similarly, cookies removed by a response
@ -28,9 +29,24 @@ use error::LaunchError;
/// This is typically the desired mode of operation for a `Client` as it removes
/// the burden of manually tracking cookies. Under some circumstances, however,
/// disabling this tracking may be desired. In these cases, use the
/// [`untracked`](Client::untracked()) constructor to create a `Client` that
/// [`untracked()`](Client::untracked()) constructor to create a `Client` that
/// _will not_ track cookies.
///
/// ### Synchronization
///
/// While `Client` implements `Sync`, using it in a multithreaded environment
/// while tracking cookies can result in surprising, non-deterministic behavior.
/// This is because while cookie modifications are serialized, the exact
/// ordering depends on when requests are dispatched. Specifically, when cookie
/// tracking is enabled, all request dispatches are serialized, which in-turn
/// serializes modifications to the internally tracked cookies.
///
/// If possible, refrain from sharing a single instance of `Client` across
/// multiple threads. Instead, prefer to create a unique instance of `Client`
/// per thread. If it's not possible, ensure that either you are not depending
/// on cookies, the ordering of their modifications, or both, or have arranged
/// for dispatches to occur in a deterministic ordering.
///
/// ## Example
///
/// The following snippet creates a `Client` from a `Rocket` instance and
@ -46,11 +62,11 @@ use error::LaunchError;
/// .dispatch();
/// ```
///
/// [`new`]: #method.new
/// [`untracked`]: #method.untracked
/// [`get`]: #method.get
/// [`put`]: #method.put
/// [`post`]: #method.post
/// [`new()`]: #method.new
/// [`untracked()`]: #method.untracked
/// [`get()`]: #method.get
/// [`put()`]: #method.put
/// [`post()`]: #method.post
pub struct Client {
rocket: Rocket,
crate cookies: Option<RwLock<CookieJar>>,