chromium/third_party/blink/renderer/core/workers/README.md

This directory contains the base implementation of all worker and worklet types. Also, this contains the implementation of the [Web Workers API](https://html.spec.whatwg.org/C/#workers) (Dedicated Worker and Shared Worker) and [Worklets API](https://drafts.css-houdini.org/worklets/).

# Worker / Worklet types

- Workers are divided into 2 types:
  - **In-process workers (Dedicated Workers)**: A worker of this type always runs in the same renderer process with a parent document that starts the worker.
  - **Out-of-process workers (Shared Workers and Service Workers)**: A worker of this type may run in a different renderer process with a parent document that starts the worker.
- Worklets are divided into 2 types:
  - **Main thread worklets (Paint Worklets and Layout Worklets)**: A worklet of this type runs on the main thread.
  - **Threaded worklets (Audio Worklets and Animation Worklets)**: A worklet of this type runs on a worker thread.

Worklets always run in the same renderer process with a parent document that starts the worklet like the in-process-workers.

# Naming conventions

Classes in this directory are named with the following conventions, there're still some exceptions though.

- `WorkerOrWorklet` prefix: Classes commonly used for workers and worklets (e.g., `WorkerOrWorkletGlobalScope`).
- `Worker` / `Worklet` prefix: Classes used for workers or worklets (e.g., `WorkerGlobalScope`).
- `Threaded` prefix: Classes used for workers and threaded worklets (e.g., `ThreadedMessagingProxyBase`).
- `MainThreadWorklet` prefix: Classes used for main thread worklets (e.g., `MainThreadWorkletReportingProxy`).

Thread hopping between the main (parent) thread and a worker thread is handled by proxy classes.

- `MessagingProxy` is the main (parent) thread side proxy that communicates to the worker thread.
- `ObjectProxy` is the worker thread side proxy that communicates to the main (parent) thread. `Object` indicates a worker/worklet JavaScript object on the parent execution context.

# Off-the-main-thread fetch

All worker subresources, and some of worker/worklet top-level scripts,
are fetched off-the-main-thread (i.e. on the worker/worklet thread).
See following docs for more details.

- [off-the-main-thread subresource fetch](https://docs.google.com/document/d/1829D6zllR1qfwvwDXHb9pjhIcbM4EZ70EiaFAaPj9YQ/edit?usp=sharing), Done.
- [off-the-main-thread top-level script fetch](https://docs.google.com/document/d/1cI6UJGdeWvlavCzfxGh3hfWy7N62Yfsu_A98RxsCyys/edit?usp=sharing), ongoing.

There are two types of network fetch on the worker/worklet thread:
insideSettings and outsideSettings fetch.
The terms insideSettings and outsideSettings are originated from
[HTML spec](https://html.spec.whatwg.org/C/#worker-processing-model) and
[Worklet spec](https://drafts.css-houdini.org/worklets/).

## insideSettings fetch

insideSettings fetch is subresource fetch.

In the spec, insideSettings corresponds to the
[worker environment settings object](https://html.spec.whatwg.org/multipage/workers.html#set-up-a-worker-environment-settings-object)
of `WorkerOrWorkletGlobalScope`.

In the implementation, insideSettings roughly corresponds to
`WorkerOrWorkletGlobalScope`.
`WorkerOrWorkletGlobalScope::Fetcher()`,
its corresponding `WorkerFetchContext`, and
`WorkerOrWorkletGlobalScope::GetContentSecurityPolicy()` are used.

Currently, all subresource fetches are already off-the-main-thread.

## outsideSettings fetch

outsideSettings fetch is off-the-main-thread top-level worker/worklet
script fetch.

In the spec, an outsideSettings is the environment settings object of
worker's parent context.

In the implementation, outsideSettings should correspond to
`Document` (or `WorkerOrWorkletGlobalScope` for nested workers), but
the worker thread can't access these objects due to threading restriction.
Therefore, we pass `FetchClientSettingsObjectSnapshot` that contains
information of these objects across threads, and create
`ResourceFetcher`, `WorkerFetchContext` and `ContentSecurityPolicy`
(separate objects from those used for insideSettings fetch)
on the worker thread.
They work as if the parent context, and are used via
`WorkerOrWorkletGlobalScope::CreateOutsideSettingsFetcher()`.

Note that, where off-the-main-thread top-level fetch is NOT enabled
(e.g. classic workers), the worker scripts are fetched on the main thread and
thus WorkerOrWorkletGlobalScope and the worker thread are not involved.

# Metrics

## UseCounter

[UseCounter](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/instrumentation/use_counter.h)
is available in all workers and worklets. The count mechanism varies based on
worker and worklet types as follows.

- Dedicated Workers and Worklets: A feature use in a dedicated worker or worklet
is propagated to the parent document, and then recorded in the document's
UseCounter. For nested dedicated workers, a feature use is propagated up to the
ancestor document via parent workers.
- Shared Workers: A feature use in a shared worker is propagated to all
documents connected to the shared worker via mojo calls, and then recorded in
their UseCounter.
- Service Workers: A feature use in a service worker is propagated to all
documents and workers being controlled by the service worker via mojo calls, and
then recorded in their UseCounter. When a feature use occurs before the service
worker finishes installing, the feature use is stored in service worker storage.
It is read whenever the installed service worker is started. See
[content/browser/service_worker/README.md](/content/browser/service_worker/README.md)
for details.

`WorkerOrWorkletGlobalScope::CountUse()` is the common entry point. For more
details, see [Design of UseCounter for
workers](https://docs.google.com/document/d/1VyYZnhjBdk-MzCRAcX37TM5-yjwTY40U_J9rWnEAo8c/edit?usp=sharing)
and [crbug 376039](https://bugs.chromium.org/p/chromium/issues/detail?id=376039).

There are some fundamental metrics.

- [WorkerStart](https://www.chromestatus.com/metrics/feature/timeline/popularity/4)
: Counts of `new DedicatedWorker()` calls in `Document` and
`DedicatedWorkerGlobalScope`.
- [ClassicDedicatedWorker](https://www.chromestatus.com/metrics/feature/timeline/popularity/3084)
: Counts of new DedicatedWorker() calls with `{ type: 'classic' }` or without `WorkerOptions#type` argument.
- [ModuleDedicatedWorker](https://www.chromestatus.com/metrics/feature/timeline/popularity/3085)
: Counts of new DedicatedWorker() calls with `{ type: 'module' }`.
- [NestedDedicatedWorker](https://www.chromestatus.com/metrics/feature/timeline/popularity/2499)
: Counts of `new DedicatedWorker()` calls in `DedicatedWorkerGlobalScope`.
- [SharedWorkerStart](https://www.chromestatus.com/metrics/feature/timeline/popularity/5)
: Counts of `new SharedWorker()` calls in `Document`.
- [ClassicSharedWorker](https://www.chromestatus.com/metrics/feature/timeline/popularity/3148)
: Counts of new SharedWorker() calls with `{ type: 'classic' }` or without `WorkerOptions#type` argument.
- [ModuleSharedWorker](https://www.chromestatus.com/metrics/feature/timeline/popularity/3149)
: Counts of new SharedWorker() calls with `{ type: 'module' }`.
- [WorkletAddModule](https://www.chromestatus.com/metrics/feature/timeline/popularity/2364)
: Counts of `Worklet#addModule()` calls in `Document`. This includes all worklet
types. Each worklet type has its own counter, too.

# Tests

When you add a new worker or worklet type, please consider adding tests in
following files and directories to check integration with the underlying worker
and worklet infrastructure.

- Web Platform Tests
  - [workers/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/external/wpt/workers/)
  - [worklets/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/external/wpt/worklets/)
- Web tests
  - [webexposed/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/webexposed/)
  - [workers/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/http/tests/workers/)
  - [worklet/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/http/tests/worklet/)
- Unit tests
  - [content/browser/worker_host/](https://cs.chromium.org/chromium/src/content/browser/worker_host/)
  - [content/renderer/worker/](https://cs.chromium.org/chromium/src/content/renderer/worker/)
  - [third_party/blink/renderer/core/workers/](https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/workers/)
- Browser tests
  - [chrome/browser/chrome_worker_browsertest.cc](https://cs.chromium.org/chromium/src/chrome/browser/chrome_worker_browsertest.cc)
  - [content/browser/worker_host/worker_browsertest.cc](https://cs.chromium.org/chromium/src/content/browser/worker_host/worker_browsertest.cc)

Workers and worklets interact with various features. You should also add tests
in the following files and directories to avoid breakage.

- Web Platform Tests
  - [content-security-policy/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/external/wpt/content-security-policy/)
  - [cross-origin-embedder-policy/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/)
  - [fetch/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/external/wpt/fetch/)
  - [mixed-content/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/external/wpt/mixed-content/)
  - [performance-timeline/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/external/wpt/performance-timeline/)
  - [referrer-policy/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/external/wpt/referrer-policy/)
  - [resource-timing/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/external/wpt/resource-timing/)
  - [secure-contexts/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/external/wpt/secure-contexts/)
  - [service-workers/service-worker/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/external/wpt/service-workers/service-worker/)
  - [upgrade-insecure-requests/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/)
  - [websockets/](https://cs.chromium.org/chromium/src/third_party/blink/web_tests/external/wpt/websockets/)
- Browser tests
  - [chrome/browser/chrome_do_not_track_browsertest.cc](https://cs.chromium.org/chromium/src/chrome/browser/chrome_do_not_track_browsertest.cc)
  - [chrome/browser/chrome_worker_browsertest.cc](https://cs.chromium.org/chromium/src/chrome/browser/chrome_worker_browsertest.cc)
  - [chrome/browser/extensions/api/web_request/web_request_apitest.cc](https://cs.chromium.org/chromium/src/chrome/browser/extensions/api/web_request/web_request_apitest.cc)
  - [chrome/browser/ssl/ssl_browsertest.cc](https://cs.chromium.org/chromium/src/chrome/browser/ssl/ssl_browsertest.cc)
  - [chrome/browser/subresource_filter/subresource_filter_browsertest.cc](https://cs.chromium.org/chromium/src/chrome/browser/subresource_filter/subresource_filter_browsertest.cc)
  - [content/browser/do_not_track_browsertest.cc](https://cs.chromium.org/chromium/src/content/browser/do_not_track_browsertest.cc)

# References

- [ES Modules for Shared Workers](https://docs.google.com/document/d/1sSdYdSOLd5zvnNGeVNlBqfTZs_VRPIrrigV3SlMnWjg/edit?usp=sharing) (Feb 19, 2020)
- [WorkerGlobalScope Initialization](https://docs.google.com/document/d/1JCv8TD2nPLNC2iRCp_D1OM4I3uTS0HoEobuTymaMqgw/edit?usp=sharing) (April 1, 2019)
- [Worker / Worklet Internals](https://docs.google.com/presentation/d/1GZJ3VnLIO_Pw0jr9nRw6_-trg68ol-AkliMxJ6jo6Bo/edit?usp=sharing) (April 19, 2018)
- [ES Modules for Dedicated Workers](https://docs.google.com/document/d/1IMGWAK7Wq37mLehwkbysNRBBnhQBo3z2MbYyMkViEnY/edit?usp=sharing) (Mar 8, 2018)
- [Design of UseCounter for workers](https://docs.google.com/document/d/1VyYZnhjBdk-MzCRAcX37TM5-yjwTY40U_J9rWnEAo8c/edit?usp=sharing) (Feb 14, 2017)