Bug 1231213 Comment 6 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

This is the current, and hopefully final, strategy:

## New IPDL Protocols

### `PRemoteWorkerController`

The Remote Worker infrastructure operates over `PBackground`, with the parent-process-side endpoint being `RemoteWorkerController` and the child-process-side endpoint being `RemoteWorkerChild`. To integrate `ServiceWorkerPrivate` into this system, it needs to access a `RemoteWorkerController`. This will happen over the `PRemoteWorkerController` protocol, which connects the main thread and background thread in the parent process.

### `PFetchEventOp`

`PFetchEventOp` is a `PBackground`-managed protocol that connects the main thread and background thread in the parent process. A `PFetchEventOp` actor represents an in-progress Fetch event. i.e., the lifetime of a `FetchEventOpChild` corresponds to the lifetime of a `FetchEvent` (more or less).

`FetchEventOpChild` will keep a reference to a `KeepAliveToken` as well as an `nsIInterceptedChannel` and can manipulate the intercepted channel on behalf of the content process. `FetchEventOpChild` should be able to synthesize a response from an `InternalResponse`, avoiding the need to use the channel abstraction. On the other hand, `FetchEventOpParent` creates `PFetchEventOpProxy` actors (see below).

### `PFetchEventOpProxy`

Commands/queries/operations from the content process can’t directly access the parent-process main thread due to the Remote Worker infrastructure existing exclusively over `PBackground`, so `PFetchEventOpProxy` acts as a proxy for the `PFetchEventOp` protocol. `FetchEventOpParent` will own a `FetchEventOpProxyParent`.

### `ServiceWorkerOpArgs` (not a protocol, but still IPC related)

`ServiceWorkerOpArgs` is an IPDL union of all possible service worker “operations” (e.g. `ServiceWorkerFetchEventOpArgs`, `ServiceWorkerMessageEventOpArgs`, etc.). Everything necessary to construct a service worker event/runnable is packaged into a struct and sent through the various protocols and to the content process as a `ServiceWorkerOpArgs` union. `RemoteWorkerChild` will ultimately determine what specific operation is received and handle is accordingly.

### `ServiceWorkerOpResult`

`ServiceWorkerOpResult` is similar to `ServiceWorkerOpArgs`; it’s used to communicate the result of an operation (and any necessary callback arguments) across IPC.

## Determining when an operation is complete

For those operations that only have one dispatch/response cycle (which is looking like everything but Fetch), the lifetime of the operation corresponds to the lifetime of the `MozPromise` returned by `PRemoteWorkerControllerChild::SendExecServiceWorkerOp` (called by `ServiceWorkerPrivate`). This promise is then resolved or rejected by the `MozPromise` returned by `PRemoteWorkerParent::SendExecServiceWorkerOp` (called by `RemoteWorkerController`).

For Fetch, this is determined by the `FetchEventOp(Proxy)` actors’ lifetimes rather than a `MozPromises`’ lifetimes, in a similar fashion.

## Summary

Service worker operations are encapsulated by a `ServiceWorkerOpArgs` object that can be sent across IPC. The path of a `ServiceWorkerOpArgs` object is `ServiceWorkerPrivate` -> `RemoteWorkerControllerChild` -> `RemoteWorkerControllerParent` -> `RemoteWorkerController` -> `RemoteWorkerParent` -> `RemoteWorkerChild` -> `WorkerPrivate`. There are many objects to pass through due to this whole process happening over 3 threads.

When a non-fetch operation completes in the content process, the steps for telling the parent process that the operation has completed is as follow:
1) Create a `ServiceWorkerOpResult` that’s used to call a `PRemoteWorkerChild::ExecServiceWorkerOpResolver`
2) That call will then resolve the promise returned from `PRemoteWorkerParent::SendExecServiceWorkerOp`, whose resolution then calls `PRemoteWorkerControllerParent::ExecServiceWorkerOpResolver`
3) That call them will resolve the promise returned from `PRemoteWorkerControllerChild::SendExecServiceWorkerOp`, where callbacks, if any, can then be called.
4) The operation is complete, and its associated `KeepAliveToken` is destroyed.

Steps for a Fetch operation are similar but use `FetchEventOp(Proxy)` actor destruction rather than `MozPromise` resolution/rejection.
This is the current, and hopefully final, strategy:

## New IPDL Protocols

### `PRemoteWorkerController`

The Remote Worker infrastructure operates over `PBackground`, with the parent-process-side endpoint being `RemoteWorkerController` and the child-process-side endpoint being `RemoteWorkerChild`. To integrate `ServiceWorkerPrivate` into this system, it needs to access a `RemoteWorkerController`. This will happen over the `PRemoteWorkerController` protocol, which connects the main thread and background thread in the parent process.

### `PFetchEventOp`

`PFetchEventOp` is a `PBackground`-managed protocol. A `PFetchEventOp` actor represents an in-progress Fetch event. i.e., the lifetime of an actor corresponds to the lifetime of a `FetchEvent` (more or less). There will be two pairs of actors implementing PFetchEventOp{Parent,Child}; one to link the main/background threads in the main process, and one to link the background thread in the main process to the Worker Launcher thread in the content process (where RemoteWorkerChild lives). Commands/queries/operations from the content process can’t directly access the parent-process main thread due to the Remote Worker infrastructure existing exclusively over `PBackground`, so the second pair of actors is needed to act as a proxy for the first pair of actors.

The child actor from the first pair will keep a reference to a `KeepAliveToken` as well as an `nsIInterceptedChannel` and can manipulate the intercepted channel on behalf of the content process. It should be able to synthesize a response from an `InternalResponse`, avoiding the need to use the channel abstraction.

### `PFetchEventOpProxy`


### `ServiceWorkerOpArgs` (not a protocol, but still IPC related)

`ServiceWorkerOpArgs` is an IPDL union of all possible service worker “operations” (e.g. `ServiceWorkerFetchEventOpArgs`, `ServiceWorkerMessageEventOpArgs`, etc.). Everything necessary to construct a service worker event/runnable is packaged into a struct and sent through the various protocols and to the content process as a `ServiceWorkerOpArgs` union. `RemoteWorkerChild` will ultimately determine what specific operation is received and handle is accordingly.

### `ServiceWorkerOpResult`

`ServiceWorkerOpResult` is similar to `ServiceWorkerOpArgs`; it’s used to communicate the result of an operation (and any necessary callback arguments) across IPC.

## Determining when an operation is complete

For those operations that only have one dispatch/response cycle (which is looking like everything but Fetch), the lifetime of the operation corresponds to the lifetime of the `MozPromise` returned by `PRemoteWorkerControllerChild::SendExecServiceWorkerOp` (called by `ServiceWorkerPrivate`). This promise is then resolved or rejected by the `MozPromise` returned by `PRemoteWorkerParent::SendExecServiceWorkerOp` (called by `RemoteWorkerController`).

For Fetch, this is determined by the `FetchEventOp` actors’ lifetimes rather than a `MozPromises`’ lifetimes, in a similar fashion.

## Summary

Service worker operations are encapsulated by a `ServiceWorkerOpArgs` object that can be sent across IPC. The path of a `ServiceWorkerOpArgs` object is `ServiceWorkerPrivate` -> `RemoteWorkerControllerChild` -> `RemoteWorkerControllerParent` -> `RemoteWorkerController` -> `RemoteWorkerParent` -> `RemoteWorkerChild` -> `WorkerPrivate`. There are many objects to pass through due to this whole process happening over 3 threads.

When a non-fetch operation completes in the content process, the steps for telling the parent process that the operation has completed is as follow:
1) Create a `ServiceWorkerOpResult` that’s used to call a `PRemoteWorkerChild::ExecServiceWorkerOpResolver`
2) That call will then resolve the promise returned from `PRemoteWorkerParent::SendExecServiceWorkerOp`, whose resolution then calls `PRemoteWorkerControllerParent::ExecServiceWorkerOpResolver`
3) That call them will resolve the promise returned from `PRemoteWorkerControllerChild::SendExecServiceWorkerOp`, where callbacks, if any, can then be called.
4) The operation is complete, and its associated `KeepAliveToken` is destroyed.

Steps for a Fetch operation are similar but use `FetchEventOp` actor destruction rather than `MozPromise` resolution/rejection.
This is the current, and hopefully final, strategy:

## New IPDL Protocols

### `PRemoteWorkerController`

The Remote Worker infrastructure operates over `PBackground`, with the parent-process-side endpoint being `RemoteWorkerController` and the child-process-side endpoint being `RemoteWorkerChild`. To integrate `ServiceWorkerPrivate` into this system, it needs to access a `RemoteWorkerController`. This will happen over the `PRemoteWorkerController` protocol, which connects the main thread and background thread in the parent process.

### `PFetchEventOp`

`PFetchEventOp` is a `PBackground`-managed protocol. A `PFetchEventOp` actor represents an in-progress Fetch event. i.e., the lifetime of an actor corresponds to the lifetime of a `FetchEvent` (more or less). There will be two pairs of actors implementing PFetchEventOp{Parent,Child}; one to link the main/background threads in the main process, and one to link the background thread in the main process to the Worker Launcher thread in the content process (where RemoteWorkerChild lives). Commands/queries/operations from the content process can’t directly access the parent-process main thread due to the Remote Worker infrastructure existing exclusively over `PBackground`, so the second pair of actors is needed to act as a proxy for the first pair of actors.

The child actor from the first pair will keep a reference to a `KeepAliveToken` as well as an `nsIInterceptedChannel` and can manipulate the intercepted channel on behalf of the content process. It should be able to synthesize a response from an `InternalResponse`, avoiding the need to use the channel abstraction.

### `ServiceWorkerOpArgs` (not a protocol, but still IPC related)

`ServiceWorkerOpArgs` is an IPDL union of all possible service worker “operations” (e.g. `ServiceWorkerFetchEventOpArgs`, `ServiceWorkerMessageEventOpArgs`, etc.). Everything necessary to construct a service worker event/runnable is packaged into a struct and sent through the various protocols and to the content process as a `ServiceWorkerOpArgs` union. `RemoteWorkerChild` will ultimately determine what specific operation is received and handle is accordingly.

### `ServiceWorkerOpResult`

`ServiceWorkerOpResult` is similar to `ServiceWorkerOpArgs`; it’s used to communicate the result of an operation (and any necessary callback arguments) across IPC.

## Determining when an operation is complete

For those operations that only have one dispatch/response cycle (which is looking like everything but Fetch), the lifetime of the operation corresponds to the lifetime of the `MozPromise` returned by `PRemoteWorkerControllerChild::SendExecServiceWorkerOp` (called by `ServiceWorkerPrivate`). This promise is then resolved or rejected by the `MozPromise` returned by `PRemoteWorkerParent::SendExecServiceWorkerOp` (called by `RemoteWorkerController`).

For Fetch, this is determined by the `FetchEventOp` actors’ lifetimes rather than a `MozPromises`’ lifetimes, in a similar fashion.

## Summary

Service worker operations are encapsulated by a `ServiceWorkerOpArgs` object that can be sent across IPC. The path of a `ServiceWorkerOpArgs` object is `ServiceWorkerPrivate` -> `RemoteWorkerControllerChild` -> `RemoteWorkerControllerParent` -> `RemoteWorkerController` -> `RemoteWorkerParent` -> `RemoteWorkerChild` -> `WorkerPrivate`. There are many objects to pass through due to this whole process happening over 3 threads.

When a non-fetch operation completes in the content process, the steps for telling the parent process that the operation has completed is as follow:
1) Create a `ServiceWorkerOpResult` that’s used to call a `PRemoteWorkerChild::ExecServiceWorkerOpResolver`
2) That call will then resolve the promise returned from `PRemoteWorkerParent::SendExecServiceWorkerOp`, whose resolution then calls `PRemoteWorkerControllerParent::ExecServiceWorkerOpResolver`
3) That call them will resolve the promise returned from `PRemoteWorkerControllerChild::SendExecServiceWorkerOp`, where callbacks, if any, can then be called.
4) The operation is complete, and its associated `KeepAliveToken` is destroyed.

Steps for a Fetch operation are similar but use `FetchEventOp` actor destruction rather than `MozPromise` resolution/rejection.

Back to Bug 1231213 Comment 6