Open Bug 1899507 Opened 1 year ago Updated 4 months ago

Off-main-thread Worker ScriptLoader

Categories

(Core :: DOM: Workers, enhancement, P2)

enhancement

Tracking

()

ASSIGNED

People

(Reporter: edenchuang, Assigned: edenchuang)

References

(Depends on 1 open bug, Blocks 5 open bugs)

Details

Attachments

(4 files, 1 obsolete file)

This is part of bug 1672491. This bug is specific to making Worker ScriptLoader work off-main thread. To be more specific, fetching the script off-main thread (maybe through PFetch).

Assignee: nobody → echuang
Blocks: 1672491
Severity: -- → S3
Status: NEW → ASSIGNED
Priority: -- → P2

Re: PFetch, Note that right now the ScriptLoader in the content-process when working for ServiceWorkers does a Cache API check then falls back to a network fetch. I think we could potentially restructure this to help reduce latency and ideally reduce complexity.

Specifically, we have 2 modes of ServiceWorker script loading:

  1. During the install phase, we need to go to the network and add things to the cache if they aren't there.
  2. Once installed, we never go to network and if something isn't in the cache, it's an error.

For the installed case, it seems reasonable that we could run a MatchAll() call once on the chrome namespace Cache where we have stored the script pieces. We can then hold these InternalResponses in a map and not have to do any dynamic lookups as the load requests come in. The caveat is that unless we also support dynamic lookups, we would need to hold onto all of the responses other than the root script once the evaluation phase completes because it is still possible to call importScripts() at runtime.

The installation phase could potentially then also use this rep where it would not do queries; we would just add responses to the map as we fetch them. For simplicity, I think this would suggest that we want to do the Cache API calls from the spawned worker rather than having the ServiceWorkerManager pre-emptively do something to cause the parent process to perform the MatchAll and send the results to the newly spawned worker. This is because that we we already have the Cache instance around for the install phase, but also because it doesn't create any new interesting edge-cases.

An interesting question is whether we could use Cache::Add{All} to simplify things, since it also internalizes the fetch; the answer is probably no because it explicitly sets the destination to subresource, but it's worth sanity checking the idea.

Duplicate of this bug: 1797639
Blocks: 1899509
Duplicate of this bug: 1049079
Blocks: 1944242

This patch introduces a new load handler PFetchLoadHandler for WorkerScriptLoader.
PFetchLoadHandler uses the PFetch to send the request to the parent process and create a channel on the parent process, then send the response back to the content process Worker thread.
Then saving the response into the cache if needed.

The basic workflow of PFetchLoadHandler is

  1. Extract the InternalRequest from WorkerScriptLoader and ThreadSafeRequsetHandle.
  2. Create the Promise and PFetch pairs and setup the corresponding FetchOpArgs for script fetching.
  3. Call FetchChild::DoFetchOp(FetchOpArgs) to parent process to perform the script fetching through FetchService/FetchInstance/FetchDriver.
  4. Once the the script fetching complete, the response will be propagated to the content process Worker thread by PFetch and resolve the created Promise in the step2.
  5. PFetchLoadHandler is the Promise's handler to setup WorkerScriptLoader with response's headers and pump with the response's body for reading.
  6. Once the stream reading is done, OnStreamComplete() will be called to setup for executing the script.
  7. In the end, call ThreadSafeRequestHandle::OnStreamComplete() to trigger the script executing on the Worker thread.

Depends on D250249

This patch uses PFetchLoadHandler in WorkerScriptLoader to perform the script loading.
If the Worker is running on the parent thread, the script loading will fallback to use NetworkLoadHandler and CacheLoadHandler, this is because the channel must be created and opened on the parent process main thread.

Depends on D250250

Attachment #9489026 - Attachment description: WIP: Bug 1899507 - P1 Preference to control WorkerScriptLoader uses PFetch for script loading. r=dom-worker-reviewers → Bug 1899507 - P1 Preference to control WorkerScriptLoader uses PFetch for script loading. r=asuth
Attachment #9489027 - Attachment description: WIP: Bug 1899507 - P2 implement PFetchLoadHandler → Bug 1899507 - P2 implement PFetchLoadHandler. r=asuth
Attachment #9489028 - Attachment description: WIP: Bug 1899507 - P3 Integrate WorkerScriptLoader and PFetchLoadHandler. → Bug 1899507 - P3 Integrate WorkerScriptLoader and PFetchLoadHandler. r=asuth
Attachment #9489027 - Attachment description: Bug 1899507 - P2 implement PFetchLoadHandler. r=asuth → Bug 1899507 - P2 Making FetchChild be a Top-Level IPC and can run with MozPromise for internal use. r=asuth
Attachment #9489028 - Attachment description: Bug 1899507 - P3 Integrate WorkerScriptLoader and PFetchLoadHandler. r=asuth → Bug 1899507 - P3 Implement PFetchLoader for WorkerScriptLoader to perform script loading in the Worker Thread. r=asuth

This patch introduces a new load handler PFetchLoadHandler for WorkerScriptLoader.
PFetchLoadHandler uses the PFetch to send the request to the parent process and create a channel on the parent process, then send the response back to the content process Worker thread.

The basic workflow of PFetchLoadHandler is

  1. Extract the InternalRequest from WorkerScriptLoader and ThreadSafeRequsetHandle.
  2. Create PFetch IPCs and setup the corresponding FetchOpArgs for script fetching.
  3. Call FetchChild::DoFetchOp(FetchOpArgs) to parent process to perform the script fetching through FetchService/FetchInstance/FetchDriver.
  4. Once the the script fetching complete, the response will be propagated to the content process Worker thread by PFetch and trigger the response handling.
  5. PFetchLoadHandler::ReceivedResponse() is called when response is avaiable, it update the WorkerScriptLoader and ThreadSafeRequestHandler according to response's headers and creates pump with the response's body for reading.
  6. Once the stream reading is done, PFetchLoadHandler::OnStreamComplete() is called to complete the script loading and try to execute the script.

Depends on D250251

See Also: → 1967540
No longer blocks: 1899509
Depends on: 1967540
No longer blocks: 1944242
See Also: 1967540

This patch introduces a new load handler PFetchLoadHandler for WorkerScriptLoader.
PFetchLoadHandler uses the PFetch to send the request to the parent process and create a channel on the parent process, then send the response back to the content process Worker thread.

The basic workflow of PFetchLoadHandler is

  1. Extract the InternalRequest from WorkerScriptLoader and ThreadSafeRequsetHandle.
  2. Create PFetch IPCs and setup the corresponding FetchOpArgs for script fetching.
  3. Call FetchChild::DoFetchOp(FetchOpArgs) to parent process to perform the script fetching through FetchService/FetchInstance/FetchDriver.
  4. Once the the script fetching complete, the response will be propagated to the content process Worker thread by PFetch and trigger the response handling.
  5. PFetchLoadHandler::ReceivedResponse() is called when response is avaiable, it update the WorkerScriptLoader and ThreadSafeRequestHandler according to response's headers and creates pump with the response's body for reading.
  6. Once the stream reading is done, PFetchLoadHandler::OnStreamComplete() is called to complete the script loading and try to execute the script.

Depends on D250251

Attachment #9505151 - Attachment is obsolete: true
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: