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.
73
74There are a few cases where we provide more firm guarantees:
75
76#### Tests
77
78There are test-only APIs in Rust, C++, and Javascript.
79These do not await a flush of child process metric values.
80You can use the test-only method `testFlushAllChildren` on the `FOG`
81XPCOM component to await child data's arrival:
82```js
83let FOG = Cc["@mozilla.org/toolkit/glean;1"].createInstance(Ci.nsIFOG);
84await FOG.testFlushAllChildren();
85```
86See [the test documentation](testing.md) for more details on testing.
87
88#### Built-in Pings
89
90[Built-in pings](https://mozilla.github.io/glean/book/user/pings/index.html)
91will send only after all metric values from all child processes have been collected.
92
93We cannot at this time provide the same guarantee for
94[Custom Pings](https://mozilla.github.io/glean/book/user/pings/custom.html).
95
96#### Shutdown
97
98We will make a best effort during an orderly shutdown to flush all pending data in child processes.
99This means a disorderly shutdown (usually a crash)
100may result in child process data being lost.
101
102### Mechanics
103
104At present
105(see [bug 1641989](https://bugzilla.mozilla.org/show_bug.cgi?id=1641989))
106FOG uses messages on the PContent protocol.
107This enables communication between content child processes and the parent process.
108
109The rough design is that the Parent can request an immediate flush of pending data,
110and each Child can decide to flush its pending data whenever it wishes.
111
112Pending Data is a buffer of bytes generated by `bincode` in Rust in the Child,
113handed off to C++, passed over IPC,
114then given back to `bincode` in Rust on the Parent.
115
116Rust is then responsible for turning the pending data into
117[metric API](../user/api.md) calls on the metrics in the parent process.
118