1
1
# How actors are organized
2
2
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.
4
9
They are organized in a hierarchy for easier lifecycle and memory management:
5
10
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)
7
12
8
13
The overall hierarchy of actors looks like this:
9
14
10
15
```
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)
13
43
|
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.
21
46
|
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.
45
87
```
46
88
47
89
## RootActor
@@ -50,84 +92,95 @@ The root actor is special. It is automatically created when a client connects.
50
92
It has a special ` actorID ` which is unique and is "root".
51
93
All other actors have an ` actorID ` which is computed dynamically,
52
94
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.
54
98
55
99
```
56
100
RootActor (root.js)
57
101
|
58
102
|-- 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
+ |
60
106
| Returned by "listTabs" or "getTab" requests.
61
107
|
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)
66
113
| 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)
68
115
| 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)
70
117
|
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)
77
119
|
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.
83
122
|
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
+
89
130
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.
98
131
```
99
132
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.
102
134
103
135
But note that this is now considered as a deprecated codepath.
104
136
Ideally, all targets should be retrieved via the new WatcherActor.
105
137
For now, the WatcherActor only support tabs and entire browser debugging.
106
138
Workers and add-ons still have to go through descriptor's getTarget.
107
139
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
+
108
167
## Target Actors
109
168
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.
114
174
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).
120
177
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.
125
179
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 .
128
182
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:
131
184
- threadActor:
132
185
ThreadActor instance for the given target,
133
186
only defined once ` attach ` request is called, or on construction.
@@ -165,7 +218,7 @@ children of a given target actor.
165
218
166
219
The data they return is filtered to reflect the target. For example, the
167
220
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 .
169
222
170
223
These actors may extend this hierarchy by having their own children, like
171
224
LongStringActor, WalkerActor, etc.
@@ -175,3 +228,9 @@ actor lists the actor ID for each one, but the actor modules aren't actually
175
228
loaded and instantiated at that point. Once the first request for a given
176
229
target-scoped actor is received by the server, that specific actor is
177
230
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