Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(385)

Side by Side Diff: net/docs/life-of-a-feature.md

Issue 2700673002: [net] Add documentation for feature process & supported platforms (Closed)
Patch Set: Feedback Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | net/docs/supported-projects.md » ('j') | net/docs/supported-projects.md » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Life of a Feature
2
3 In the years since the Chromium browser was first open-sourced, the `//net`
4 directory has expanded from being the basis of loading web content in the
5 Chromium browser to accomodating a wide variety of networking needs,
xunjieli 2017/02/16 21:11:25 nit: s/accomodating/accommodating
6 both in the Chromium browser and in other Google and third-party products
7 and projects.
8
9 This brings with it many new opportunities, such as the ability to
10 introduce new protocols rapidly or push Web security forward, as well as
11 new challenges, such as how to balance the needs of various `//net`
12 consumers effectively.
13
14 To make it easier to contribute new features or to change existing
15 behaviours in `//net`, this document tries to capture the life of a
16 feature in `//net`, from initial design to the eventual possibility of
17 deprecation and removal.
18
19 ## Supported Projects
20
21 When considering the introduction of a new `//net` feature or changing
22 a `//net` behaviour, it's first necessary to understand where `//net`
xunjieli 2017/02/16 21:11:25 optional nit: s/behaviour/behavior assuming there
23 is used, how it is used, and what the various constraints and limits are.
24
25 To understand a more comprehensive matrix of the supported platforms and
26 constraints, see [Supported Projects](supported-projects.md). When
27 examining a new feature request, or a change in behaviour, it's necessary
28 to consider dimensions such as:
29
30 * Does this feature apply to all supported projects, or is this something
31 like a Browser-only feature?
32 * Does this feature apply to all supported platforms, or is this something
33 specific to a particular subset?
34 * Is the feature a basic networking library feature, or is it specific to
35 something in the Web Platform?
36 * Will some projects wish to strip the feature in order to meet targets
37 such as memory usage (RAM) or binary size?
38 * Does it depend on Google services or Google-specific behaviours or
39 features?
40 * How will this feature be tested / experimented with? For example,
41 __Field Trials (Finch)__ and __User Metrics (UMA)__ may not be available
42 on a number of platforms.
43 * How risky is the feature towards compatibility/stability? How will it
44 be undone if there is a bug?
45 * Are the power/memory/CPU/bandwidth requirements appropriate for the
46 targetted projects and/or platforms?
xunjieli 2017/02/16 21:11:25 optional nit: s/targetted/targeted if there is a g
47
48 ## Design and Layering
49
50 Once the supported platforms and constraints are identified, it's necessary
51 to determine how to actually design the feature to meet those constraints,
52 in hopefully the easiest way possible both for implementation and consumption.
53
54 ### Designing for multiple platforms
55
56 In general, `//net` features try to support all platforms with a common
57 interface, and generally eschew OS-specific interfaces from being exposed as
58 part of `//net`.
59
60 Cross-platform code is generally done via declaring an interface named
61 `foo.h`, which is common for all platforms, and then using the build-system to
62 do compile-time switching between implementations in `foo_win.cc`, `foo_mac.cc`,
63 `foo_android.cc`, etc.
64
65 The goal is to ensure that consumers generally don't have to think about
66 OS-specific considerations, and can instead code to the interface.
67
68 ### Designing for multiple products
69
70 While premature abstraction can significantly harm readability, if it is
71 anticipated that different products will have different implementation needs,
72 or may wish to selectively disable the feature, it's often necessary to
73 abstract that interface sufficiently in `//net` to allow for dependency
74 injection.
Randy Smith (Not in Mondays) 2017/02/16 21:07:23 I think an abstract example or two would be useful
Ryan Sleevi 2017/02/16 23:29:33 I'm going to leave this for you to fill in, as I'm
Randy Smith (Not in Mondays) 2017/02/17 18:01:09 That's fine; happy to do that in a follow-on CL.
Ryan Sleevi 2017/02/17 18:07:17 Do you feel like those examples belong in this doc
Randy Smith (Not in Mondays) 2017/02/17 18:27:25 In general, what I want in this doc is to have eno
Ryan Sleevi 2017/02/17 22:44:54 I see. I think I had a very different mental image
75
76 This is true whether discussing concrete classes and interfaces or something
77 as simple a boolean configuration flag that different consumers wish to set
78 differently.
79
80 The two most common approaches in `//net` are injection and delegation.
81
82 #### Injection
83
84 Injection refers to the pattern of defining the interface or concrete
85 configuration parameter (such as a boolean), along with the concrete
86 implementation, but requiring the `//net` embedder to supply it (perhaps
Randy Smith (Not in Mondays) 2017/02/16 21:07:23 Suggestion: "it" -> "an instantiation of the imple
87 optionally).
88
89 Examples of this pattern include things such as the `ProxyConfigService`,
90 which has concrete implementations in `//net` for a variety of platforms'
91 configuration of proxies, but which requires it be supplied as part of the
92 `URLRequestContextGetter` building, if proxies are going to be supported.
93
94 An example of injecting configuration flags can be seen in the
95 `HttpNetworkSession::Params` structure, which is used to provide much of
96 the initialization parameters for the HTTP layer.
97
98 While the ideal form of injection is to pass ownership of the injected
99 object, such as via a `std::unique_ptr<Foo>`, there are a number of places
100 in `//net` in which ownership is shared / left to the embedder, and the
101 injected object is passed around as a naked/raw pointer.
Randy Smith (Not in Mondays) 2017/02/16 21:07:23 Hmmm. I'd imagine we'd want to move away from thi
102
103 #### Delegation
104
105 Delegation refers to forcing the `//net` embedder to respond to specific
106 delegated calls via a Delegate interface that it implements. In general,
107 when using the delegated pattern, ownership of the delegate should be
xunjieli 2017/02/16 21:11:25 nit: should it be "delegate pattern"/"delegation p
108 transferred, so that the lifetime and threading semantics are clear and
109 unambiguous.
110
111 That is, for a given class `Foo`, which has a `Foo::Delegate` interface
112 defined to allow embedders to alter behaviour, prefer a constructor that
113 is
114 ```
115 explicit Foo(std::unique_ptr<Delegate> delegate);
116 ```
117 so that it is clear that the lifetime of `delegate` is determined by
118 `Foo`.
119
120 The most notable example of the delegate pattern is `URLRequest::Delegate`.
Randy Smith (Not in Mondays) 2017/02/16 21:07:23 The most notable example violates the "ownership i
Ryan Sleevi 2017/02/16 23:29:33 I'm not sure I agree. Does the expansion about "le
Randy Smith (Not in Mondays) 2017/02/17 18:01:09 Can you give me a more direct pointer to the legac
Ryan Sleevi 2017/02/17 18:07:17 I see the point of confusion. It's in the bit imme
Randy Smith (Not in Mondays) 2017/02/17 18:27:25 I'm torn here, just because in the process of this
Ryan Sleevi 2017/02/17 22:44:54 I actually don't, but I also recognize how signifi
121
122 While the use of a `base::Callback` can also be considered a form of
123 delegation, the `//net` layer tries to eschew any callbacks that can be
124 called more than once, and instead favors defining class interfaces
125 with concrete behavioural requirements in order to ensure the correct
126 lifetimes of objects and to adjust over time. When `//net` takes a
127 callback (e.g. `net::CompletionCallback`), the intended pattern is to
128 signal the asynchronous completion of a single method, invoking that
129 callback at most once before deallocating it. For more discussion
130 of these patterns, see [Code Patterns](code-patterns.md).
131
132 ### Understanding the Layering
133
134 A significant challenge many feature proposals face is understanding the
135 layering in `//net` and what different portions of `//net` are allowed to
136 know.
137
138 #### Socket Pools
139
140 The most common challenge feature proposals encounter is the awareness
141 that the act of associating an actual request to make with a socket is
142 done lazily, referred to as "late-binding".
143
144 With late-bound sockets, a given `URLRequest` will not be assigned an actual
145 transport connection until the request is ready to be sent. This allows for
146 reprioritizing requests as they come in, to ensure that higher priority requests
147 get preferential treatment, but it also means that features or data associated
148 with a `URLRequest` generally don't participate in socket establishment or
149 maintenance.
150
151 For example, a feature that wanted to associate the low-level network socket
xunjieli 2017/02/16 21:11:25 nit: s/wanted/wants since the rest of the paragrap
152 with a `URLRequest` during connection establishment is not something that the
153 `//net` design supports, since the `URLRequest` is kept unaware of how sockets
154 are established by virtue of the socket pools and late binding. This allows for
155 more flexibility when working to improve performance, such as the ability to
156 coalesce multiple logical 'sockets' over a single HTTP/2 or QUIC stream, which
157 may only have a single physical network socket involved.
158
159 #### Making Additional Requests
160
161 From time to time, `//net` feature proposals will involve needing to load
162 a secondary resource as part of processing. For example, SDCH involves loading
163 additional dictionaries that are advertised in a header, and other feature
164 proposals have involved fetching a `/.well-known/` URI or reporting errors to
165 a particular URL.
166
167 This is particularly challenging, because often, these features are implemented
168 deeper in the network stack, such as [`//net/cert`](../cert), [`//net/http`](../ http),
169 or [`//net/filter`](../filter), which [`//net/url_request`](../url_request) depe nds
170 on. Because `//net/url_request` depends on these low-level directories, it would
171 be a circular dependency to have these directories depend on `//net/url_request` ,
172 and circular dependencies are forbidden.
173
174 The recommended solution to address this is to adopt the delegation or injection
175 patterns. The lower-level directory will define some interface that represents t he
176 "I need this URL" request, and then elsewhere, in a directory allowed to depend
177 on `//net/url_request`, an implementation of that interface/delegate that uses
178 `//net/url_request` is implemented.
Randy Smith (Not in Mondays) 2017/02/16 21:07:22 I feel like this needs to be fleshed out some; thi
Ryan Sleevi 2017/02/16 23:29:33 I'm not sure I really understand this feedback, or
Randy Smith (Not in Mondays) 2017/02/17 18:01:09 Let's talk about this in our VC today. Not blocki
179
180 ### Understanding the Lifetimes
181
182 Understanding the object lifetime and dependency graph can be one of the largest
183 challenges to contributing and maintaining `//net`. As a consequence, features
184 which require introducing more complexity to the lifetimes of objects generally
185 have a greater challenge to acceptance.
186
187 When designing features, features which model object lifetimes as a hierarchal
xunjieli 2017/02/16 21:11:25 nit: consider revising the subject of this sentenc
xunjieli 2017/02/16 21:11:25 I slightly prefer "hierachical" over "hierarchal."
188 DAG are much more likely to be reviewed and accepted than features which rely on
189 the use of either reference counting or weak pointers to maintain ownership.
Randy Smith (Not in Mondays) 2017/02/16 21:07:23 I think that we need to writeup, somewhere, a just
Ryan Sleevi 2017/02/16 23:29:33 I'm also not sure how to interpret this comment, a
Randy Smith (Not in Mondays) 2017/02/17 18:01:09 Not a blocker. This document is already solidly i
190
191 In addition to preferring explicit lifetimes, such as through judicious use of
192 `std::unique_ptr<>` to indicate ownership transfer of dependencies, many
193 features in `//net` also expect that if a `base::Callback` is involved (which
194 includes `net::CompletionCallback`), then it's possible that invoking the
195 callback may result in the deletion of the current (calling) object. As
196 further expanded upon in [Code Patterns](code-patterns.md), features and
197 changes should be designed such that any callback invocation is the last
198 bit of code executed, and that the callback is accessed via the stack (such
199 as through the use of either `base::ResetAndReturn(callback_).Run()` or
200 `std::move(callback_).Run()`.
201
202 ### Specs: What Are They Good For
203
204 As `//net` is used as the basis for a number of browsers, it's an important part
205 of the design philosophy to ensure behaviours are well-specified, and that the
206 implementation conforms to those specifications. This may be seen as burdensome
207 when it's unclear whether or not a feature will 'take off,' but it's equally
208 critical to ensure that the Chromium projects do not fork the Web Platform.
209
210 #### Incubation Is Required
211
212 `//net` respects Chromium's overall position of [incubation first](https://group s.google.com/a/chromium.org/d/msg/blink-dev/PJ_E04kcFb8/baiLN3DTBgAJ) standards development.
213
214 With an incubation first approach, before introducing any new features that
215 might be exposed over the wire to servers, whether they be explicit behaviours
216 such as adding new headers to implicit behaviours such as
xunjieli 2017/02/16 21:11:25 nit: s/to/or whether explicit behaviors [or] impl
217 [Happy Eyeballs](https://tools.ietf.org/html/rfc6555), should have some form
218 of specification written. That specification should at least be on an
219 incubation track, and the expectation is that the specification should have a
220 direct path to an appropriate standards track. Features which don't adhere to
221 this pattern, or which are not making progress towars a standards track, will
xunjieli 2017/02/16 21:11:25 nit: s/towars/towards
222 require a high-level approvals, to ensure that the Platform doesn't fragment.
xunjieli 2017/02/16 21:11:25 nit: remove 'a'
223
224 #### Introducing New Headers
225
226 A common form of feature request is the introduction of new headers, either via
227 the `//net` implementation directly, or through consuming `//net` interfaces
228 and modifying headers on the fly.
229
230 The introduction of any additional headers SHOULD have an incubated spec attache d,
231 ideally with cross-vendor interest. Particularly, headers which only apply to
232 Google or Google services are very likely to be rejected outright.
233
234 #### Making Additional Requests
235
236 While it's necessary to provide abstraction around `//net/url_request` for
237 any lower-level components that may need to make additional requests, for most
238 features, that's not all that is necessary. Because `//net/url_request` only
239 provides a basic HTTP fetching mechanism, it's insufficient for any Web Platform
240 feature, because it doesn't consider the broader platform concerns such as
241 interactions with CORS, Service Workers, cookie and authentication policies, or
242 even basic interactions with optional features like Extensions or SafeBrowsing.
243
244 To account for all of these things, any resource fetching that is to support
245 a feature of the Web Platform, whether because the resource will be directly
246 exposed to web content (for example, an image load or prefetch) or because it
247 is in response to invoking a Web Platform API (for example, invoking the
248 credential management API), the feature's resource fetching should be
249 explainable in terms of the [Fetch Living Standard](https://fetch.spec.whatwg.o rg/).
250 The Fetch standard defines a JavaScript API for fetching resources, but more
251 importantly, defines a common set of infrastructure and terminology that
252 tries to define how all resource loads in the Web Platform happen - whether
253 it be through the JavaScript API, through `XMLHttpRequest`, or the `src`
254 attribute in HTML tags, for example.
255
256 This also includes any resource fetching that wishes to use the same socket
257 pools or caches as the Web Platform, to ensure that every resource that is
258 web exposed (directly or indirectly) was fetched in a consistent and
xunjieli 2017/02/16 21:11:25 nit: s/was/is
259 well-documented way, thus minimizing platform fragmentation and security
260 issues.
261
262 There are exceptions to this, however, but they're generally few and far
263 between. In general, any feature that needs to define an abstraction to
264 allow it to "fetch resources," likely needs to also be "explained in terms
265 of Fetch".
Randy Smith (Not in Mondays) 2017/02/16 21:07:22 I think this needs to have some implementation bac
Ryan Sleevi 2017/02/16 23:29:33 While I agree, I think that belongs in something l
Randy Smith (Not in Mondays) 2017/02/17 18:01:09 Yep, I'm completely with you. We need to flesh th
266
267 ## Implementation
268
269 In general, prior to implementing, try to get a review on net-dev@chromium.org
270 for the general feedback and design review.
271
272 In addition to the net-dev@chromium.org early review, `//net` requires that any
273 browser-exposed behaviour should also adhere to the
274 [Blink Process](https://www.chromium.org/blink#new-features), which includes an
275 "Intent to Implement" message to blink-dev@chromium.org
276
277 For features that are unclear about their future, such as experiments or trials,
278 it's also expected that the design planning will also account for how features
279 will be removed cleanly. For features that radically affect the architecture of
280 `//net`, expect a high bar of justification, since reversing those changes if
281 it fails to pan out can cause significant disruption to productivity and
xunjieli 2017/02/16 21:11:25 nit: they fail to pan out assuming "it" means "tho
282 stability.
283
284 ## Deprecation
285
286 Plan for obsolence, hope for success. Similar to implementation, features that
287 are to be removed should also go through the
288 [Blink Process](https://www.chromium.org/blink#TOC-Web-Platform-Changes:-Process )
289 for removing features.
290
291 Note that due to the diversity of [Supported Projects](supported-projects.md),
292 removing a feature while minimizing disruption can be just as complex as adding
293 a feature. For example, relying solely on __User Metrics (UMA)__ to signal the
294 safety of removing a feature may not consider all projects, and relying on
295 __Field Trials (Finch)__ to assess risk or restore the 'legacy' behaviour may no t
296 work on all projects either.
297
298 It's precisely because of these challenges that there's such a high bar for
299 adding features, because they may represent multi-year committments to support,
xunjieli 2017/02/16 21:11:25 nit: s/committments/commitments
300 even when the feature itself is deprecated or targetted for removal.
OLDNEW
« no previous file with comments | « no previous file | net/docs/supported-projects.md » ('j') | net/docs/supported-projects.md » ('J')

Powered by Google App Engine
This is Rietveld 408576698