Repository: servo/servo
File: components/script/fetch.rs (Rust)

Code before:

    // Step 12. Set controller to the result of calling fetch given request and
    // processResponse given response being these steps:
    global.fetch_with_network_listener(request_init, network_listener);

    // Step 13. Return p.
    promise
}

/// <https://fetch.spec.whatwg.org/#queue-a-deferred-fetch>
fn queue_deferred_fetch(
    request: NetTraitsRequest,
    activate_after: Finite<f64>,
    global: &GlobalScope,
) -> DeferredFetchRecordId {
    let trusted_global = Trusted::new(global);
    let mut request = request;
    // Step 1. Populate request from client given request.
    request.client = Some(global.request_client());
    request.populate_request_from_client();
    // Step 2. Set request’s service-workers mode to "none".
    request.service_workers_mode = ServiceWorkersMode::None;
    // Step 3. Set request’s keepalive to true.
    request.keep_alive = true;
    // Step 4. Let deferredRecord be a new deferred fetch record whose request is request, and whose notify invoked is onActivatedWithoutTermination.
    let deferred_record = Rc::new(DeferredFetchRecord {
        request,
        global: trusted_global.clone(),
        invoke_state: Cell::new(DeferredFetchRecordInvokeState::Pending),
        activated: Cell::new(false),
    });
    // Step 5. Append deferredRecord to request’s client’s fetch group’s deferred fetch records.
    let deferred_fetch_record_id = global.append_deferred_fetch(deferred_record);
    // Step 6. If activateAfter is non-null, then run the following steps in parallel:
    global.schedule_timer(TimerEventRequest {
        callback: Box::new(move || {
            // Step 6.2. Process deferredRecord.
            let global = trusted_global.root();
            global.deferred_fetch_record_for_id(&deferred_fetch_record_id).process();

            // Last step of https://fetch.spec.whatwg.org/#process-a-deferred-fetch
            //
            // Step 4. Queue a global task on the deferred fetch task source with
            // deferredRecord’s request’s client’s global object to run deferredRecord’s notify invoked.
            let trusted_global = trusted_global.clone();
            global.task_manager().deferred_fetch_task_source().queue(
                task!(notify_deferred_record: move || {
                    trusted_global.root().deferred_fetch_record_for_id(&deferred_fetch_record_id).activate();
                }),
            );
        }),

Review comment (suggestion):
The record seems to be moved into the fetch group, so I don't see the need fro the rc. 

I'm guessing it's needed because of the various cloning of the records, but as per my other comments I think those can be changed into mutable operations on the record in an method of fetch group. 

Code after:

    // Step 12. Set controller to the result of calling fetch given request and
    // processResponse given response being these steps:
    global.fetch_with_network_listener(request_init, network_listener);

    // Step 13. Return p.
    promise
}

/// <https://fetch.spec.whatwg.org/#queue-a-deferred-fetch>
fn queue_deferred_fetch(
    request: NetTraitsRequest,
    activate_after: Finite<f64>,
    global: &GlobalScope,
) -> DeferredFetchRecordId {
    let trusted_global = Trusted::new(global);
    let mut request = request;
    // Step 1. Populate request from client given request.
    request.client = Some(global.request_client());
    request.populate_request_from_client();
    // Step 2. Set request’s service-workers mode to "none".
    request.service_workers_mode = ServiceWorkersMode::None;
    // Step 3. Set request’s keepalive to true.
    request.keep_alive = true;
    // Step 4. Let deferredRecord be a new deferred fetch record whose request is request, and whose notify invoked is onActivatedWithoutTermination.
    let deferred_record = Rc::new(DeferredFetchRecord {
        request,
        invoke_state: Cell::new(DeferredFetchRecordInvokeState::Pending),
        activated: Cell::new(false),
    });
    // Step 5. Append deferredRecord to request’s client’s fetch group’s deferred fetch records.
    let deferred_fetch_record_id = global.append_deferred_fetch(deferred_record);
    // Step 6. If activateAfter is non-null, then run the following steps in parallel:
    global.schedule_timer(TimerEventRequest {
        callback: Box::new(move || {
            // Step 6.2. Process deferredRecord.
            let global = trusted_global.root();
            global.deferred_fetch_record_for_id(&deferred_fetch_record_id).process(&global);

            // Last step of https://fetch.spec.whatwg.org/#process-a-deferred-fetch
            //
            // Step 4. Queue a global task on the deferred fetch task source with
            // deferredRecord’s request’s client’s global object to run deferredRecord’s notify invoked.
            let trusted_global = trusted_global.clone();
            global.task_manager().deferred_fetch_task_source().queue(
                task!(notify_deferred_record: move || {
                    trusted_global.root().deferred_fetch_record_for_id(&deferred_fetch_record_id).activate();
                }),
            );
        }),
        // Step 6.1. The user agent should wait until any of the following conditions is met: