File: storage.md

package info (click to toggle)
firefox 143.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,617,328 kB
  • sloc: cpp: 7,478,492; javascript: 6,417,157; ansic: 3,720,058; python: 1,396,372; xml: 627,523; asm: 438,677; java: 186,156; sh: 63,477; makefile: 19,171; objc: 13,059; perl: 12,983; yacc: 4,583; cs: 3,846; pascal: 3,405; lex: 1,720; ruby: 1,003; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 53; csh: 10
file content (76 lines) | stat: -rw-r--r-- 4,093 bytes parent folder | download | duplicates (18)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# Storage Panel Architecture

## Actor structure

This is the new architecture that is being implemented to support Fission. It's currently used when inspecting tabs.

![Class structure architecture (resource-based)](storage/resources.svg)

- We no longer have a global `Storage` actor.
- The specific actors for each storage type are spawned by watchers instead.
- The reference to a global `Storage` actor that each actor has now points to a mock instead.
- Some watchers require to be run in the parent process, while others can be run in the content process.
  - Parent process: Cookies, IndexedDB, Web Extension.
  - Content process: LocalStorage, SessionStorage, Cache.

## Flow

Some considerations to keep in mind:

- In the Storage Panel, **resources are fronts**.
- These fronts contain a `hosts` object, which is populated with the host name, and the actual storage data it contains.
- In the client, we get as part of the `onAvailable` callback of `ResourceCommand.watchResources`:
  - Content process storage types: multiple resources, one per target
  - Parent process storage types: a single resource

### Initial load

Web page loaded, open toolbox. Later on, we see what happens if a new remote target is added (for instance, an iframe is created that points to a different host).

#### Fission OFF

![Initial load diagram, fission off](storage/flow-fission-off.svg)

- We get all the storage fronts as new resources sent in the `onAvailable` callback for `watchResources`.
- After a remote target has been added, we get new additions as `"single-store-update"` events.

#### Fission ON

![Initial load diagram, fission on](storage/flow-fission-on.svg)

Similar to the previous scenario (fission off), but now when a new remote target is added:

- We get content process storage resources in a new `onAvailable` callback, instead of `"single-store-update"`.
- Parent process storage resources keep using the `"single-store-update"` method. This is possible due to their `StorageMock` actors emitting a fake `"window-ready"` event after a `"window-global-created"`.

### Navigation

#### Fission ON, target switching OFF

![Navigation diagram, fission on, target switching off](storage/navigation-fission-on-target-switching-off.svg)

- Deletion of content process storage hosts is handled within the `onTargetDestroyed` callback.
- Deletion of parent process storage hosts is handled with `"single-store-update"` events, fired when the `StorageMock` detects a `"window-global-destroyed"` event.
- When the new target is available, new storage actors are spawned from their watchers' `watch` method and are sent as resources in the `onAvailable` callback.

#### Fission ON, target switching ON

![Navigation diagram, fission on, target switching off](storage/navigation-fission-on-target-switching-on.svg)

Similar to the previous scenario (fission on, target switching off), but parent process storage resources are handled differently, since their watchers remain instantiated.

- New actors for parent process resources are not spawned by their watchers `watch`, but as a callback of `"window-global-created"`.
- Some times there's a race condition between a target being available and firing `"window-global-created"`. There is a delay to send the resource to the client, to ensure that any `onTargetAvailable` callback is processed first.
  - The new actor/resource is sent after a `"target-available-form"` event.

### CRUD operations

#### Add a new cookie

Other CRUD operations work very similar to this one.

![CRUD operation diagram, add a new cookie](storage/crud-cookie.svg)

- We call `StorageMock.getWindowFromHost` so we can get the storage principal. Since this is a parent process resource, it doesn't have access to an actual window, so it returns a mock instead (but with a real principal).
- To detect changes in storage, we subscribe to different events that platform provides via `Services.obs.addObserver`.
- To manipulate storage data, we use different methods depending on the storage type. For cookies, we use the API provided by `Services.cookies`.