1# Inter-process Communication (IPC)
2
3Firefox Desktop is a multi-process desktop application.
4Code requiring instrumentation may be on any of its processes,
5so FOG provide facilities to do just that.
6
7## Design
8
9The IPC Design of FOG was worked out in
10[bug 1618253](https://bugzilla.mozilla.org/show_bug.cgi?id=1618253).
11
12It centred around a few specific concepts:
13
14### Forbidding Non-Commutative Operations
15
16Because we cannot nicely impose a canonical ordering of metric operations across all processes,
17FOG forbids non-[commutative](https://en.wikipedia.org/wiki/Commutative_property)
18metric operations in some circumstances.
19
20For example,
21`Add()`-ing to a Counter metric works from multiple processes because the order doesn't matter.
22However, given a String metric being `Set()` from multiple processes simultaneously,
23which value should it take?
24
25This ambiguity is not a good foundation to build trust on,
26so we forbid setting a String metric from multiple processes.
27
28#### List of Forbidden Operations
29
30* Boolean's `set` (this is the metric type's only operation)
31* Labeled Boolean's `set` (this is the metric type's only operation)
32* String's `set` (this is the metric type's only operation)
33* Labeled String's `set` (this is the metric type's only operation)
34* String List's `set`
35    * `add` is permitted (order and uniqueness are not guaranteed)
36* Timespan's `start`, `stop`, and `cancel` (these are the metric type's only operations)
37* UUID's `set` and `generateAndSet` (these are the metric type's only operations)
38* Datetime's `set` (this is the metric type's only operation)
39* Quantity's `set` (this is the metric type's only operation)
40
41This list may grow over time as new metric types are added.
42If there's an operation/metric type on this list that you need to use in a non-parent process,
43please reach out
44[on the #glean channel](https://chat.mozilla.org/#/room/#glean:mozilla.org)
45and we'll help you out.
46
47### Process Agnosticism
48
49For metric types that can be used cross-process,
50FOG provides no facility for identifying which process the instrumentation is on.
51
52What this means is that if you accumulate to a
53[Timing Distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html)
54in multiple processes,
55all the samples from all the processes will be combined in the same metric.
56
57If you wish to distinguish samples from different process types,
58you will need multiple metrics and inline code to select the proper one for the given process.
59For example:
60
61```C++
62if (XRE_GetProcessType() == GeckoProcessType_Default) {
63  mozilla::glean::performance::cache_size.Accumulate(numBytes / 1024);
64} else {
65  mozilla::glean::performance::non_main_process_cache_size.Accumulate(numBytes / 1024);
66}
67```
68
69### Scheduling
70
71FOG makes no guarantee about when non-main-process metric values are sent across IPC.
72FOG will try its best to schedule opportunistically in idle moments,
73and during orderly shutdowns.
74
75There are a few cases where we provide more firm guarantees:
76
77#### Tests
78
79There are test-only APIs in Rust, C++, and Javascript.
80These do not await a flush of child process metric values.
81You can use the test-only method `testFlushAllChildren` on the `FOG`
82XPCOM component to await child data's arrival:
83```js
84await Services.fog.testFlushAllChildren();
85```
86See [the test documentation](testing) for more details on testing FOG.
87For writing tests about instrumentation, see
88[the instrumentation test documentation](../user/instrumentation_tests).
89
90#### Pings
91
92We do not guarantee that non-main-process data has made it into a specific ping.
93
94[Built-in pings](https://mozilla.github.io/glean/book/user/pings/index.html)
95are submitted by the Rust Glean SDK at times FOG doesn't directly control,
96so there may be data not present in the parent process when a built-in ping is submitted.
97We don't anticipate this causing a problem since child-process data that
98"misses" a given ping will be included in the next one.
99
100At this time,
101[Custom Pings](https://mozilla.github.io/glean/book/user/pings/custom.html)
102must be sent in the parent process and have no mechanism
103to schedule their submission for after child-process data arrives in the parent process.
104[bug 1732118](https://bugzilla.mozilla.org/show_bug.cgi?id=1732118)
105tracks the addition of such a mechanism or guarantee.
106
107#### Shutdown
108
109We will make a best effort during an orderly shutdown to flush all pending data in child processes.
110This means a disorderly shutdown (usually a crash)
111may result in child process data being lost.
112
113#### Size
114
115We don't measure or keep an up-to-date calculation of the size of the IPC Payload.
116We do, however, keep a count of the number of times the IPC Payload has been accessed.
117This is used as a (very) conservative estimate of the size of the IPC Payload so we do not exceed the
118[IPC message size limit](https://searchfox.org/mozilla-central/search?q=kMaximumMessageSize).
119
120See [bug 1745660](https://bugzilla.mozilla.org/show_bug.cgi?id=1745660).
121
122### Mechanics
123
124The rough design is that the parent process can request an immediate flush of pending data,
125and each child process can decide to flush its pending data whenever it wishes.
126The former is via `FlushFOGData() returns (ByteBuf)` and the latter via  `FOGData(ByteBuf)`.
127
128Pending Data is a buffer of bytes generated by `bincode` in Rust in the Child,
129handed off to C++, passed over IPC,
130then given back to `bincode` in Rust on the Parent.
131
132Rust is then responsible for turning the pending data into
133[metrics API][glean-metrics] calls on the metrics in the parent process.
134
135#### Supported Process Types
136
137FOG supports messaging between the following types of child process and the parent process:
138* content children (via `PContent`
139  (for now. See [bug 1641989](https://bugzilla.mozilla.org/show_bug.cgi?id=1641989))
140* gmp children (via `PGMP`)
141* gpu children (via `PGPU`)
142* rdd children (via `PRDD`)
143* socket children (via `PSocketProcess`)
144
145See
146[the process model docs](/dom/ipc/process_model.rst)
147for more information about what that means.
148
149### Adding Support for a new Process Type
150
151Adding support for a new process type is a matter of extending the two messages
152mentioned above in "Mechanics" to another process type's protocol (ipdl file).
153
1541. Add two messages to the appropriate sections in `P<ProcessType>.ipdl`
155    * (( **Note:** `PGPU` _should_ be the only ipdl where `parent`
156      means the non-parent/-main/-UI process,
157      but double-check that you get this correct.))
158    * Add `async FOGData(ByteBuf&& aBuf);` to the parent/main/UI process side of things
159      (most often `parent:`).
160    * Add `async FlushFOGData() returns (ByteBuf buf);` to the non-parent/-main/-UI side
161      (most often `child:`).
1622. Implement the protocol endpoints in `P<ProcessType>{Child|Parent}.{h|cpp}`
163    * The message added to the `parent: ` section goes in
164      `P<ProcessType>Parent.{h|cpp}` and vice versa.
1653. Add to `FOGIPC.cpp`'s `FlushAllChildData` code that
166    1. Enumerates all processes of the newly-supported type (there may only be one),
167    2. Calls `SendFlushFOGData on each, and
168    3. Adds the resulting promise to the array.
1694. Add to `FOGIPC.cpp`'s `SendFOGData` the correct `GeckoProcessType_*`
170   enum value, and appropriate code for getting the parent process singleton and calling
171   `SendFOGData` on it.
1725. Add to the fog crate's `register_process_shutdown` function
173   handling for at-shutdown flushing of IPC data.
174   If this isn't added, we will log (but not panic)
175   on the first use of Glean APIs on an unsupported process type.
176    * "Handling" might be an empty block with a comment explaining where to find it
177      (like how `PROCESS_TYPE_DEFAULT` is handled)
178    * Or it might be custom code
179      (like `PROCESS_TYPE_CONTENT`'s)
1806. Add to the documented [list of supported process types](#supported-process-types)
181   the process type you added support for.
182
183[glean-metrics]: https://mozilla.github.io/glean/book/reference/metrics/index.html
184