Skip to content

Commit 6c9420a

Browse files
committed
Bug 1836856 - [devtools] Update actors documentation. r=devtools-reviewers,bomsy
This is a long overdue update to better describe the key actors: root, descriptor, watcher, target and target-scope actors. Differential Revision: https://phabricator.services.mozilla.com/D181136
1 parent 689594b commit 6c9420a

File tree

1 file changed

+145
-86
lines changed

1 file changed

+145
-86
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,89 @@
11
# How actors are organized
22

3-
To start with, actors are living within devtools/server/actors folder.
3+
tl;dr; The Root actor exposes Descriptor actors which describe a debuggable context.
4+
The Descriptor then exposes a dedicated Watcher actor.
5+
The Watcher actor notifies about many target actors (one per smaller debuggable context: WindowGlobal, worker,...)
6+
and also notifies about all resources (console messages, sources, network events,...).
7+
8+
To start with, actors are living within [devtools/server/actors][actors-folder] folder.
49
They are organized in a hierarchy for easier lifecycle and memory management:
510
once a parent is removed from the pool, its children are removed as well.
6-
(See actor-registration.md for more information about how to implement one)
11+
(See [actor-registration.md](actor-registration.md) for more information about how to implement a new one)
712

813
The overall hierarchy of actors looks like this:
914

1015
```
11-
RootActor: First one, automatically instantiated when we start connecting.
12-
| Mostly meant to instantiate new actors.
16+
### RootActor:
17+
|
18+
| First one, automatically instantiated when we start connecting
19+
| with a fixed actor ID set to "root".
20+
|
21+
| It is mostly meant to instantiate all the following actors.
22+
|
23+
|-- Global-scoped actors:
24+
|
25+
| Actors exposing features related to the main process, that are not
26+
| specific to any particular target (document, tab, add-on, or worker).
27+
| These actors are registered with `global: true` in:
28+
| devtools/server/actors/utils/actor-registry.js
29+
|
30+
| Examples:
31+
| * PreferenceActor (for Firefox prefs)
32+
| * DeviceActor (for fetching and toggling runtime specifics)
33+
| * PerfActor (used by the profiler.firefox.com profiler)
34+
| * ...
35+
|
36+
\-- Descriptor actors
37+
|
38+
| These actors expose information about a particular context that DevTools can focus on:
39+
| * a tab (TabDescriptor)
40+
| * a (service/shared/chrome) worker (WorkerDescriptor)
41+
| * a Web Extension (WebExtensionDescriptor)
42+
| * the browser (ProcessDescriptor)
1343
|
14-
|-- Global-scoped actors:
15-
| Actors exposing features related to the main process, that are not
16-
| specific to any particular target (document, tab, add-on, or worker).
17-
| These actors are registered with `global: true` in
18-
| devtools/server/actors/utils/actor-registry.js
19-
| Examples include:
20-
| PreferenceActor (for Firefox prefs)
44+
| This actor is mostly informative. It exposes a WatcherActor to actually debug this context.
45+
| This is typically used by about:debugging to display all available debuggable contexts.
2146
|
22-
\-- Descriptor Actor's -or- Watcher Actor
23-
|
24-
\ -- Target actors:
25-
Actors that represent the main "thing" being targeted by a given toolbox,
26-
such as a tab, frame, worker, add-on, etc. and track its lifetime.
27-
Generally, there is a target actor for each thing you can point a
28-
toolbox at.
29-
Examples include:
30-
WindowGlobalTargetActor (for a WindowGlobal, such as a tab or a remote iframe)
31-
ProcessTargetActor
32-
WorkerTargetActor (for various kind of workers)
33-
|
34-
\-- Target-scoped actors:
35-
Actors exposing one particular feature set. They are children of a
36-
given target actor and the data they return is filtered to reflect
37-
the target.
38-
These actors are registered with `target: true` in
39-
devtools/server/actors/utils/actor-registry.js
40-
Examples include:
41-
WebConsoleActor
42-
InspectorActor
43-
These actors may extend this hierarchy by having their own children,
44-
like LongStringActor, WalkerActor, etc.
47+
\ -- WatcherActor
48+
|
49+
| Each descriptor actor exposes a dedicated Watcher actor instance.
50+
| This actor allows to observe target actors and resources.
51+
|
52+
\ -- Target actors:
53+
|
54+
| Within a given descriptor/watcher context, targets represents fine grained debuggable contexts.
55+
| While the descriptor and watcher stays alive until the devtools are closed or the debuggable context
56+
| was close (tab closed, worker destroyed or browser closed),
57+
| the targets have a shorter lifecycle and a narrowed scope.
58+
|
59+
| The typical target actors are WindowGlobal target actors.
60+
| This represents one specific WindowGlobal. A tab is typically made of many of them.
61+
| Each iframe will have its dedicated WindowGlobal.
62+
| Each navigation will also spawn a new dedicated WindowGlobal.
63+
| When debugging an add-on, you will have one WindowGlobal target for the background page,
64+
| one for each popup, ...
65+
|
66+
| The other targets actors are:
67+
| * worker targets
68+
| * process targets (only used in the Browser Toolbox to debug the browser itself made of many processes)
69+
|
70+
\ -- Target-scoped actors:
71+
72+
Actors exposing one particular feature set. They are children of a
73+
given target actor and the data they return is filtered to reflect
74+
the target.
75+
These actors are registered with `target: true` in
76+
devtools/server/actors/utils/actor-registry.js
77+
78+
Examples:
79+
* WebConsoleActor (for evaluating javascript)
80+
* InspectorActor (to observe and modify the DOM Elements)
81+
* ThreadActor (for setting breakpoints and pause/step/resume)
82+
* StorageActor (for managing storage data)
83+
* AccessibilityActor (to observe accessibility information)
84+
85+
These actors may extend this hierarchy by having their own children,
86+
like LongStringActor, WalkerActor, SourceActor, NodeActor, etc.
4587
```
4688

4789
## RootActor
@@ -50,84 +92,95 @@ The root actor is special. It is automatically created when a client connects.
5092
It has a special `actorID` which is unique and is "root".
5193
All other actors have an `actorID` which is computed dynamically,
5294
so that you need to ask an existing actor to create an Actor
53-
and returns its `actorID`. That's the main role of RootActor.
95+
and returns its `actorID`.
96+
That's the main role of RootActor. It will expose all the descriptor actors,
97+
which is only the start of spawning the watcher, target and target-scoped actors.
5498

5599
```
56100
RootActor (root.js)
57101
|
58102
|-- TabDescriptorActor (descriptors/tab.js)
59-
| Targets frames (such as a tab) living in the parent or child process.
103+
|
104+
| Designates tabs running in the parent or child process.
105+
|
60106
| Returned by "listTabs" or "getTab" requests.
61107
|
62-
|-- WorkerTargetActor (worker.js)
63-
| Targets a worker (applies to various kinds like web worker, service
64-
| worker, etc.).
65-
| Returned by "listWorkers" request to the root actor to get all workers.
108+
|-- WorkerDescriptorActor (descriptors/worker.js)
109+
|
110+
| Designates any type of worker: web worker, service worker, shared worker, chrome worker.
111+
|
112+
| Returned by "listWorkers" request to the root actor to get all workers. (/!\ this is an expensive method)
66113
| Returned by "listWorkers" request to a WindowGlobalTargetActor to get
67-
| workers for a specific document/WindowGlobal.
114+
| workers for a specific document/WindowGlobal. (this is a legacy, to be removed codepath)
68115
| Returned by "listWorkers" request to a ContentProcessTargetActor to get
69-
| workers for the chrome of the child process.
116+
| workers for the chrome of the child process. (this is a legacy, to be removed codepath)
70117
|
71-
|-- ParentProcessTargetActor (parent-process.js)
72-
| Targets all resources in the parent process of Firefox (chrome documents,
73-
| JSMs, JS XPCOM, etc.).
74-
| Extends the abstract class WindowGlobalTargetActor.
75-
| Extended by WebExtensionTargetActor.
76-
| Returned by "getProcess" request without any argument.
118+
|-- ParentProcessDescriptorActor (descriptors/process.js)
77119
|
78-
|-- ContentProcessTargetActor (content-process.js)
79-
| Targets all resources in a content process of Firefox (chrome sandboxes,
80-
| frame scripts, documents, etc.)
81-
| Returned by "getProcess" request with a id argument, matching the
82-
| targeted process.
120+
| Designates any parent or content processes.
121+
| This exposes all chrome documents, JSMs/ESMs, JS XPCOM, etc.
83122
|
84-
\-- WebExtensionActor (addon/webextension.js)
85-
Represents a WebExtension add-on in the parent process. This gives some
86-
metadata about the add-on and watches for uninstall events. This uses a
87-
proxy to access the actual WebExtension in the WebExtension process via
88-
the message manager.
123+
| Returned by "listProcesses" and "getProcess".
124+
|
125+
\-- WebExtensionDescriptorActor (descriptors/webextension.js)
126+
127+
Designates a WebExtension add-on in the parent process. This gives some
128+
metadata about the add-on and watches for uninstall events.
129+
89130
Returned by "listAddons" request.
90-
|
91-
\-- WebExtensionTargetActor (targets/webextension.js)
92-
Targets a WebExtension add-on. This runs in the WebExtension process.
93-
The client issues an additional "connect" request to
94-
WebExtensionActor to get this actor, which is different from the
95-
approach used for frame target actors.
96-
Extends ParentProcessTargetActor.
97-
Returned by "connect" request to WebExtensionActor.
98131
```
99132
All these descriptor actors expose a `getTarget()` method which
100-
returns the target actor for the descriptor's debuggable context
101-
(tab, worker, process or add-on).
133+
returns the target actor for the descriptor's debuggable context.
102134

103135
But note that this is now considered as a deprecated codepath.
104136
Ideally, all targets should be retrieved via the new WatcherActor.
105137
For now, the WatcherActor only support tabs and entire browser debugging.
106138
Workers and add-ons still have to go through descriptor's getTarget.
107139

140+
## Watcher Actors
141+
142+
Each descriptor exposes a dedicated Watcher actor (via getWatcher RDP method),
143+
which is scoped to the debuggable context of the descriptor.
144+
145+
This actor is about observing things.
146+
It will notify you about:
147+
* target actors via target-available-form and target-destroyed-form,
148+
* resources via resource-available-form, resource-updated-form and resource-destroyed-form.
149+
150+
## Resources
151+
152+
Resources aren't necessary actors. That can be simple JSON objects describing a particular part of the Web.
153+
Resources can be describing a console message, a JS source, a network event, ...
154+
155+
Each resource is being observed by a dedicated ResourceWatcher class implemented in [devtools/server/actors/resources/][resources-folder]
156+
where the index.js registers all the resource types.
157+
158+
These `ResourceWatcher` classes should implement a `watch()` method to start watching for a given resource type
159+
and a `destroy()` method to stop watching. One new instance will be instantiated each time we start watching for a given type.
160+
161+
These classes can be instantiated in various ways:
162+
* just from the parent process if the resource can only be observed from there (ex: network events and some storages).
163+
In such case, the watch method will receive a watcher actor as argument.
164+
* just from the target's thread, which can be a tab thread, or a worker thread.
165+
In such case, the watch method will receive a target actor as argument.
166+
108167
## Target Actors
109168

110-
Those are the actors exposed by the watcher actor, or, via descriptor's getTarget methods.
111-
They are meant to track the lifetime of a given target: document, process, add-on, or worker.
112-
It also allows to fetch the target-scoped actors connected to this target,
113-
which are actors like console, inspector, thread (for debugger), style inspector, etc.
169+
Those are the actors exposed by the watcher actor `target-available-form` event , or, via descriptor's `getTarget()` methods.
170+
They are meant to track the lifetime of a very precise debuggable piece of the descriptor context:
171+
* One precise document instance, also called `WindowGlobal`,
172+
* One worker,
173+
* One parent or content process.
114174

115-
Some target actors inherit from WindowGlobalTargetActor (defined in
116-
window-global.js) which is meant for "window globals" which present
117-
documents to the user. It automatically tracks the lifetime of the targeted
118-
window global, but it also tracks its iframes and allows switching the
119-
target to one of its iframes.
175+
Its main purpose is to expose the target-scoped actor IDs, all contained in the target form.
176+
The target form is exposed by watcher actor `target-available-form` event (or via the now deprecated descriptor's `getTarget()` method).
120177

121-
For historical reasons, target actors also handle creating the ThreadActor, used
122-
to manage breakpoints in the debugger. Actors inheriting from
123-
WindowGlobalTargetActor expose `attach`/`detach` requests, that allows to
124-
start/stop the ThreadActor.
178+
The target will be destroyed as soon as the related debuggable context.
125179

126-
Target-scoped actors are accessed via the target actor's RDP form which contains
127-
the `actorID` for each target-scoped actor.
180+
For historical reasons, target actors also handle creating the ThreadActor, used
181+
to manage breakpoints in the debugger.
128182

129-
The target-scoped actors expect to find the following properties on the target
130-
actor:
183+
The target-scoped actors expect to find the following properties on the target actor:
131184
- threadActor:
132185
ThreadActor instance for the given target,
133186
only defined once `attach` request is called, or on construction.
@@ -165,7 +218,7 @@ children of a given target actor.
165218

166219
The data they return is filtered to reflect the target. For example, the
167220
InspectorActor that you fetch from a WindowGlobalTargetActor gives you information
168-
about the markup and styles for only that frame.
221+
about the markup and styles only for the context of the target.
169222

170223
These actors may extend this hierarchy by having their own children, like
171224
LongStringActor, WalkerActor, etc.
@@ -175,3 +228,9 @@ actor lists the actor ID for each one, but the actor modules aren't actually
175228
loaded and instantiated at that point. Once the first request for a given
176229
target-scoped actor is received by the server, that specific actor is
177230
instantiated just in time to service the request.
231+
232+
The actor IDs of all these actors can be retrieve in the "form" of each target actor.
233+
The "form" is notified by the Watcher actor via `target-avaible-form` RDP packet.
234+
235+
[actors-folder]: https://searchfox.org/mozilla-central/source/devtools/server/actors/
236+
[resources-folder]: https://searchfox.org/mozilla-central/source/devtools/server/actors/resources/

0 commit comments

Comments
 (0)