mirror of
https://github.com/servo/servo.git
synced 2025-08-10 16:05:43 +01:00
net: Use RequestId
to cancel fetches instead of creating an IPC channel (#34883)
Instead of creating an IPC channel for every fetch, allow cancelling fetches based on the `RequestId` of the original request. This requires that `RequestId`s be UUIDs so that they are unique between processes that might communicating with the resource process. In addition, the resource process loop now keeps a `HashMap` or `Weak` handles to cancellers and cleans them up. This allows for creating mutiple `FetchCanceller`s in `script` for a single fetch request, allowing integration of the media and video elements to integrate with the `Document` canceller list -- meaning these fetches also get cancelled when the `Document` unloads. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
e2be55b873
commit
748954d610
23 changed files with 179 additions and 226 deletions
|
@ -464,10 +464,7 @@ pub enum WebSocketNetworkEvent {
|
|||
#[derive(Debug, Deserialize, Serialize)]
|
||||
/// IPC channels to communicate with the script thread about network or DOM events.
|
||||
pub enum FetchChannels {
|
||||
ResponseMsg(
|
||||
IpcSender<FetchResponseMsg>,
|
||||
/* cancel_chan */ Option<IpcReceiver<()>>,
|
||||
),
|
||||
ResponseMsg(IpcSender<FetchResponseMsg>),
|
||||
WebSocket {
|
||||
event_sender: IpcSender<WebSocketNetworkEvent>,
|
||||
action_receiver: IpcReceiver<WebSocketDomAction>,
|
||||
|
@ -480,13 +477,9 @@ pub enum FetchChannels {
|
|||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub enum CoreResourceMsg {
|
||||
Fetch(RequestBuilder, FetchChannels),
|
||||
Cancel(Vec<RequestId>),
|
||||
/// Initiate a fetch in response to processing a redirection
|
||||
FetchRedirect(
|
||||
RequestBuilder,
|
||||
ResponseInit,
|
||||
IpcSender<FetchResponseMsg>,
|
||||
/* cancel_chan */ Option<IpcReceiver<()>>,
|
||||
),
|
||||
FetchRedirect(RequestBuilder, ResponseInit, IpcSender<FetchResponseMsg>),
|
||||
/// Store a cookie for a given originating URL
|
||||
SetCookieForUrl(ServoUrl, Serde<Cookie<'static>>, CookieSource),
|
||||
/// Store a set of cookies for a given originating URL
|
||||
|
@ -522,10 +515,10 @@ pub enum CoreResourceMsg {
|
|||
// FIXME: https://github.com/servo/servo/issues/34591
|
||||
#[expect(clippy::large_enum_variant)]
|
||||
enum ToFetchThreadMessage {
|
||||
Cancel(Vec<RequestId>),
|
||||
StartFetch(
|
||||
/* request_builder */ RequestBuilder,
|
||||
/* response_init */ Option<ResponseInit>,
|
||||
/* cancel_chan */ Option<IpcReceiver<()>>,
|
||||
/* callback */ BoxedFetchCallback,
|
||||
),
|
||||
FetchResponse(FetchResponseMsg),
|
||||
|
@ -584,12 +577,7 @@ impl FetchThread {
|
|||
fn run(&mut self) {
|
||||
loop {
|
||||
match self.receiver.recv().unwrap() {
|
||||
ToFetchThreadMessage::StartFetch(
|
||||
request_builder,
|
||||
response_init,
|
||||
canceller,
|
||||
callback,
|
||||
) => {
|
||||
ToFetchThreadMessage::StartFetch(request_builder, response_init, callback) => {
|
||||
self.active_fetches.insert(request_builder.id, callback);
|
||||
|
||||
// Only redirects have a `response_init` field.
|
||||
|
@ -598,11 +586,10 @@ impl FetchThread {
|
|||
request_builder,
|
||||
response_init,
|
||||
self.to_fetch_sender.clone(),
|
||||
canceller,
|
||||
),
|
||||
None => CoreResourceMsg::Fetch(
|
||||
request_builder,
|
||||
FetchChannels::ResponseMsg(self.to_fetch_sender.clone(), canceller),
|
||||
FetchChannels::ResponseMsg(self.to_fetch_sender.clone()),
|
||||
),
|
||||
};
|
||||
|
||||
|
@ -623,6 +610,14 @@ impl FetchThread {
|
|||
self.active_fetches.remove(&request_id);
|
||||
}
|
||||
},
|
||||
ToFetchThreadMessage::Cancel(request_ids) => {
|
||||
// Errors are ignored here, because Servo sends many cancellation requests when shutting down.
|
||||
// At this point the networking task might be shut down completely, so just ignore errors
|
||||
// during this time.
|
||||
let _ = self
|
||||
.core_resource_thread
|
||||
.send(CoreResourceMsg::Cancel(request_ids));
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -635,7 +630,6 @@ pub fn fetch_async(
|
|||
core_resource_thread: &CoreResourceThread,
|
||||
request: RequestBuilder,
|
||||
response_init: Option<ResponseInit>,
|
||||
canceller: Option<IpcReceiver<()>>,
|
||||
callback: BoxedFetchCallback,
|
||||
) {
|
||||
let _ = FETCH_THREAD
|
||||
|
@ -643,11 +637,19 @@ pub fn fetch_async(
|
|||
.send(ToFetchThreadMessage::StartFetch(
|
||||
request,
|
||||
response_init,
|
||||
canceller,
|
||||
callback,
|
||||
));
|
||||
}
|
||||
|
||||
/// Instruct the resource thread to cancel an existing request. Does nothing if the
|
||||
/// request has already completed or has not been fetched yet.
|
||||
pub fn cancel_async_fetch(request_ids: Vec<RequestId>) {
|
||||
let _ = FETCH_THREAD
|
||||
.get()
|
||||
.expect("Tried to cancel request in process that hasn't started one.")
|
||||
.send(ToFetchThreadMessage::Cancel(request_ids));
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
||||
pub struct ResourceCorsData {
|
||||
/// CORS Preflight flag
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use base::id::{PipelineId, TopLevelBrowsingContextId};
|
||||
|
@ -14,6 +13,7 @@ use malloc_size_of_derive::MallocSizeOf;
|
|||
use mime::Mime;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use servo_url::{ImmutableOrigin, ServoUrl};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::policy_container::{PolicyContainer, RequestPolicyContainer};
|
||||
use crate::response::HttpsState;
|
||||
|
@ -21,12 +21,11 @@ use crate::{ReferrerPolicy, ResourceTimingType};
|
|||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
||||
/// An id to differeniate one network request from another.
|
||||
pub struct RequestId(usize);
|
||||
pub struct RequestId(Uuid);
|
||||
|
||||
impl RequestId {
|
||||
pub fn next() -> Self {
|
||||
static NEXT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
Self(NEXT_REQUEST_ID.fetch_add(1, Ordering::Relaxed))
|
||||
impl Default for RequestId {
|
||||
fn default() -> Self {
|
||||
Self(servo_rand::random_uuid())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,7 +282,7 @@ pub struct RequestBuilder {
|
|||
impl RequestBuilder {
|
||||
pub fn new(url: ServoUrl, referrer: Referrer) -> RequestBuilder {
|
||||
RequestBuilder {
|
||||
id: RequestId::next(),
|
||||
id: RequestId::default(),
|
||||
method: Method::GET,
|
||||
url,
|
||||
headers: HeaderMap::new(),
|
||||
|
@ -471,8 +470,9 @@ impl RequestBuilder {
|
|||
/// the Fetch spec.
|
||||
#[derive(Clone, MallocSizeOf)]
|
||||
pub struct Request {
|
||||
/// The id of this request so that the task that triggered it can route
|
||||
/// messages to the correct listeners.
|
||||
/// The unique id of this request so that the task that triggered it can route
|
||||
/// messages to the correct listeners. This is a UUID that is generated when a request
|
||||
/// is being built.
|
||||
pub id: RequestId,
|
||||
/// <https://fetch.spec.whatwg.org/#concept-request-method>
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue