A place to cache linked articles (think custom and personal wayback machine)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang=fr>
  4. <!-- Has to be within the first 1024 bytes, hence before the <title>
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset=utf-8>
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name=viewport content="width=device-width,minimum-scale=1,initial-scale=1,shrink-to-fit=no">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Notes from Facebook's Developer Infrastructure at Scale F8 Talk (archive) — David Larlet</title>
  13. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  14. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons/apple-touch-icon.png">
  15. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons/favicon-32x32.png">
  16. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons/favicon-16x16.png">
  17. <link rel="manifest" href="/manifest.json">
  18. <link rel="mask-icon" href="/static/david/icons/safari-pinned-tab.svg" color="#5bbad5">
  19. <link rel="shortcut icon" href="/static/david/icons/favicon.ico">
  20. <meta name="apple-mobile-web-app-title" content="David Larlet">
  21. <meta name="application-name" content="David Larlet">
  22. <meta name="msapplication-TileColor" content="#da532c">
  23. <meta name="msapplication-config" content="/static/david/icons/browserconfig.xml">
  24. <meta name="theme-color" content="#f0f0ea">
  25. <!-- That good ol' feed, subscribe :p. -->
  26. <link rel=alternate type="application/atom+xml" title=Feed href="/david/log/">
  27. <meta name="robots" content="noindex, nofollow">
  28. <meta content="origin-when-cross-origin" name="referrer">
  29. <!-- Canonical URL for SEO purposes -->
  30. <link rel="canonical" href="http://gregoryszorc.com/blog/2015/03/28/notes-from-facebook%27s-developer-infrastructure-at-scale-f8-talk/">
  31. <style>
  32. /* http://meyerweb.com/eric/tools/css/reset/ */
  33. html, body, div, span,
  34. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  35. a, abbr, address, big, cite, code,
  36. del, dfn, em, img, ins,
  37. small, strike, strong, tt, var,
  38. dl, dt, dd, ol, ul, li,
  39. fieldset, form, label, legend,
  40. table, caption, tbody, tfoot, thead, tr, th, td,
  41. article, aside, canvas, details, embed,
  42. figure, figcaption, footer, header, hgroup,
  43. menu, nav, output, ruby, section, summary,
  44. time, mark, audio, video {
  45. margin: 0;
  46. padding: 0;
  47. border: 0;
  48. font-size: 100%;
  49. font: inherit;
  50. vertical-align: baseline;
  51. }
  52. /* HTML5 display-role reset for older browsers */
  53. article, aside, details, figcaption, figure,
  54. footer, header, hgroup, menu, nav, section { display: block; }
  55. body { line-height: 1; }
  56. blockquote, q { quotes: none; }
  57. blockquote:before, blockquote:after,
  58. q:before, q:after {
  59. content: '';
  60. content: none;
  61. }
  62. table {
  63. border-collapse: collapse;
  64. border-spacing: 0;
  65. }
  66. /* http://practicaltypography.com/equity.html */
  67. /* https://calendar.perfplanet.com/2016/no-font-face-bulletproof-syntax/ */
  68. /* https://www.filamentgroup.com/lab/js-web-fonts.html */
  69. @font-face {
  70. font-family: 'EquityTextB';
  71. src: url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff2') format('woff2'),
  72. url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff') format('woff');
  73. font-weight: 300;
  74. font-style: normal;
  75. font-display: swap;
  76. }
  77. @font-face {
  78. font-family: 'EquityTextB';
  79. src: url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff2') format('woff2'),
  80. url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff') format('woff');
  81. font-weight: 300;
  82. font-style: italic;
  83. font-display: swap;
  84. }
  85. @font-face {
  86. font-family: 'EquityTextB';
  87. src: url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff2') format('woff2'),
  88. url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff') format('woff');
  89. font-weight: 700;
  90. font-style: normal;
  91. font-display: swap;
  92. }
  93. @font-face {
  94. font-family: 'ConcourseT3';
  95. src: url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff2') format('woff2'),
  96. url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff') format('woff');
  97. font-weight: 300;
  98. font-style: normal;
  99. font-display: swap;
  100. }
  101. /* http://practice.typekit.com/lesson/caring-about-opentype-features/ */
  102. body {
  103. /* http://www.cssfontstack.com/ Palatino 99% Win 86% Mac */
  104. font-family: "EquityTextB", Palatino, serif;
  105. background-color: #f0f0ea;
  106. color: #07486c;
  107. font-kerning: normal;
  108. -moz-osx-font-smoothing: grayscale;
  109. -webkit-font-smoothing: subpixel-antialiased;
  110. text-rendering: optimizeLegibility;
  111. font-variant-ligatures: common-ligatures contextual;
  112. font-feature-settings: "kern", "liga", "clig", "calt";
  113. }
  114. pre, code, kbd, samp, var, tt {
  115. font-family: 'TriplicateT4c', monospace;
  116. }
  117. em {
  118. font-style: italic;
  119. color: #323a45;
  120. }
  121. strong {
  122. font-weight: bold;
  123. color: black;
  124. }
  125. nav {
  126. background-color: #323a45;
  127. color: #f0f0ea;
  128. display: flex;
  129. justify-content: space-around;
  130. padding: 1rem .5rem;
  131. }
  132. nav:last-child {
  133. border-bottom: 1vh solid #2d7474;
  134. }
  135. nav a {
  136. color: #f0f0ea;
  137. }
  138. nav abbr {
  139. border-bottom: 1px dotted white;
  140. }
  141. h1 {
  142. border-top: 1vh solid #2d7474;
  143. border-bottom: .2vh dotted #2d7474;
  144. background-color: #e3e1e1;
  145. color: #323a45;
  146. text-align: center;
  147. padding: 5rem 0 4rem 0;
  148. width: 100%;
  149. font-family: 'ConcourseT3';
  150. display: flex;
  151. flex-direction: column;
  152. }
  153. h1.single {
  154. padding-bottom: 10rem;
  155. }
  156. h1 span {
  157. position: absolute;
  158. top: 1vh;
  159. left: 20%;
  160. line-height: 0;
  161. }
  162. h1 span a {
  163. line-height: 1.7;
  164. padding: 1rem 1.2rem .6rem 1.2rem;
  165. border-radius: 0 0 6% 6%;
  166. background: #2d7474;
  167. font-size: 1.3rem;
  168. color: white;
  169. text-decoration: none;
  170. }
  171. h2 {
  172. margin: 4rem 0 1rem;
  173. border-top: .2vh solid #2d7474;
  174. padding-top: 1vh;
  175. }
  176. h3 {
  177. text-align: center;
  178. margin: 3rem 0 .75em;
  179. }
  180. hr {
  181. height: .4rem;
  182. width: .4rem;
  183. border-radius: .4rem;
  184. background: #07486c;
  185. margin: 2.5rem auto;
  186. }
  187. time {
  188. display: bloc;
  189. margin-left: 0 !important;
  190. }
  191. ul, ol {
  192. margin: 2rem;
  193. }
  194. ul {
  195. list-style-type: square;
  196. }
  197. a {
  198. text-decoration-skip-ink: auto;
  199. text-decoration-thickness: 0.05em;
  200. text-underline-offset: 0.09em;
  201. }
  202. article {
  203. max-width: 50rem;
  204. display: flex;
  205. flex-direction: column;
  206. margin: 2rem auto;
  207. }
  208. article.single {
  209. border-top: .2vh dotted #2d7474;
  210. margin: -6rem auto 1rem auto;
  211. background: #f0f0ea;
  212. padding: 2rem;
  213. }
  214. article p:last-child {
  215. margin-bottom: 1rem;
  216. }
  217. p {
  218. padding: 0 .5rem;
  219. margin-left: 3rem;
  220. }
  221. p + p,
  222. figure + p {
  223. margin-top: 2rem;
  224. }
  225. blockquote {
  226. background-color: #e3e1e1;
  227. border-left: .5vw solid #2d7474;
  228. display: flex;
  229. flex-direction: column;
  230. align-items: center;
  231. padding: 1rem;
  232. margin: 1.5rem;
  233. }
  234. blockquote cite {
  235. font-style: italic;
  236. }
  237. blockquote p {
  238. margin-left: 0;
  239. }
  240. figure {
  241. border-top: .2vh solid #2d7474;
  242. background-color: #e3e1e1;
  243. text-align: center;
  244. padding: 1.5rem 0;
  245. margin: 1rem 0 0;
  246. font-size: 1.5rem;
  247. width: 100%;
  248. }
  249. figure img {
  250. max-width: 250px;
  251. max-height: 250px;
  252. border: .5vw solid #323a45;
  253. padding: 1px;
  254. }
  255. figcaption {
  256. padding: 1rem;
  257. line-height: 1.4;
  258. }
  259. aside {
  260. display: flex;
  261. flex-direction: column;
  262. background-color: #e3e1e1;
  263. padding: 1rem 0;
  264. border-bottom: .2vh solid #07486c;
  265. }
  266. aside p {
  267. max-width: 50rem;
  268. margin: 0 auto;
  269. }
  270. /* https://fvsch.com/code/css-locks/ */
  271. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  272. font-size: 1rem;
  273. line-height: calc( 1.5em + 0.2 * 1rem );
  274. }
  275. h1 {
  276. font-size: 1.9rem;
  277. line-height: calc( 1.2em + 0.2 * 1rem );
  278. }
  279. h2 {
  280. font-size: 1.6rem;
  281. line-height: calc( 1.3em + 0.2 * 1rem );
  282. }
  283. h3 {
  284. font-size: 1.35rem;
  285. line-height: calc( 1.4em + 0.2 * 1rem );
  286. }
  287. @media (min-width: 20em) {
  288. /* The (100vw - 20rem) / (50 - 20) part
  289. resolves to 0-1rem, depending on the
  290. viewport width (between 20em and 50em). */
  291. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  292. font-size: calc( 1rem + .6 * (100vw - 20rem) / (50 - 20) );
  293. line-height: calc( 1.5em + 0.2 * (100vw - 50rem) / (20 - 50) );
  294. margin-left: 0;
  295. }
  296. h1 {
  297. font-size: calc( 1.9rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  298. line-height: calc( 1.2em + 0.2 * (100vw - 50rem) / (20 - 50) );
  299. }
  300. h2 {
  301. font-size: calc( 1.5rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  302. line-height: calc( 1.3em + 0.2 * (100vw - 50rem) / (20 - 50) );
  303. }
  304. h3 {
  305. font-size: calc( 1.35rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  306. line-height: calc( 1.4em + 0.2 * (100vw - 50rem) / (20 - 50) );
  307. }
  308. }
  309. @media (min-width: 50em) {
  310. /* The right part of the addition *must* be a
  311. rem value. In this example we *could* change
  312. the whole declaration to font-size:2.5rem,
  313. but if our baseline value was not expressed
  314. in rem we would have to use calc. */
  315. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  316. font-size: calc( 1rem + .6 * 1rem );
  317. line-height: 1.5em;
  318. }
  319. p, li, pre, details {
  320. margin-left: 3rem;
  321. }
  322. h1 {
  323. font-size: calc( 1.9rem + 1.5 * 1rem );
  324. line-height: 1.2em;
  325. }
  326. h2 {
  327. font-size: calc( 1.5rem + 1.5 * 1rem );
  328. line-height: 1.3em;
  329. }
  330. h3 {
  331. font-size: calc( 1.35rem + 1.5 * 1rem );
  332. line-height: 1.4em;
  333. }
  334. figure img {
  335. max-width: 500px;
  336. max-height: 500px;
  337. }
  338. }
  339. figure.unsquared {
  340. margin-bottom: 1.5rem;
  341. }
  342. figure.unsquared img {
  343. height: inherit;
  344. }
  345. @media print {
  346. body { font-size: 100%; }
  347. a:after { content: " (" attr(href) ")"; }
  348. a, a:link, a:visited, a:after {
  349. text-decoration: underline;
  350. text-shadow: none !important;
  351. background-image: none !important;
  352. background: white;
  353. color: black;
  354. }
  355. abbr[title] { border-bottom: 0; }
  356. abbr[title]:after { content: " (" attr(title) ")"; }
  357. img { page-break-inside: avoid; }
  358. @page { margin: 2cm .5cm; }
  359. h1, h2, h3 { page-break-after: avoid; }
  360. p3 { orphans: 3; widows: 3; }
  361. img {
  362. max-width: 250px !important;
  363. max-height: 250px !important;
  364. }
  365. nav, aside { display: none; }
  366. }
  367. ul.with_columns {
  368. column-count: 1;
  369. }
  370. @media (min-width: 20em) {
  371. ul.with_columns {
  372. column-count: 2;
  373. }
  374. }
  375. @media (min-width: 50em) {
  376. ul.with_columns {
  377. column-count: 3;
  378. }
  379. }
  380. ul.with_two_columns {
  381. column-count: 1;
  382. }
  383. @media (min-width: 20em) {
  384. ul.with_two_columns {
  385. column-count: 1;
  386. }
  387. }
  388. @media (min-width: 50em) {
  389. ul.with_two_columns {
  390. column-count: 2;
  391. }
  392. }
  393. .gallery {
  394. display: flex;
  395. flex-wrap: wrap;
  396. justify-content: space-around;
  397. }
  398. .gallery figure img {
  399. margin-left: 1rem;
  400. margin-right: 1rem;
  401. }
  402. .gallery figure figcaption {
  403. font-family: 'ConcourseT3'
  404. }
  405. footer {
  406. font-family: 'ConcourseT3';
  407. display: flex;
  408. flex-direction: column;
  409. border-top: 3px solid white;
  410. padding: 4rem 0;
  411. background-color: #07486c;
  412. color: white;
  413. }
  414. footer > * {
  415. max-width: 50rem;
  416. margin: 0 auto;
  417. }
  418. footer a {
  419. color: #f1c40f;
  420. }
  421. footer .avatar {
  422. width: 200px;
  423. height: 200px;
  424. border-radius: 50%;
  425. float: left;
  426. -webkit-shape-outside: circle();
  427. shape-outside: circle();
  428. margin-right: 2rem;
  429. padding: 2px 5px 5px 2px;
  430. background: white;
  431. border-left: 1px solid #f1c40f;
  432. border-top: 1px solid #f1c40f;
  433. border-right: 5px solid #f1c40f;
  434. border-bottom: 5px solid #f1c40f;
  435. }
  436. </style>
  437. <h1>
  438. <span><a id="jumper" href="#jumpto" title="Un peu perdu ?">?</a></span>
  439. Notes from Facebook's Developer Infrastructure at Scale F8 Talk (archive)
  440. <time>Pour la pérennité des contenus liés. Non-indexé, retrait sur simple email.</time>
  441. </h1>
  442. <section>
  443. <article>
  444. <h3><a href="http://gregoryszorc.com/blog/2015/03/28/notes-from-facebook%27s-developer-infrastructure-at-scale-f8-talk/">Source originale du contenu</a></h3>
  445. <p>Any time Facebook talks about technical matters I tend to listen.
  446. They have a track record of demonstrating engineering leadership
  447. in several spaces. And, unlike many companies that just talk, Facebook
  448. often gives others access to those ideas via source code and healthy
  449. open source projects. It's rare to see a company operating on the
  450. frontier of the computing field provide so much insight into their
  451. inner workings. You can gain so much by riding their cotails and
  452. following their lead instead of clinging to and cargo culting from
  453. the past.</p>
  454. <p>The Facebook F8 developer conference was this past week. All the
  455. talks are <a href="https://developers.facebooklive.com/">now available online</a>.
  456. <strong>I encourage you to glimpse through the list of talks and watch
  457. whatever is relevant to you.</strong> There's really a little bit for
  458. everyone.</p>
  459. <p>Of particular interest to me is the
  460. <a href="https://developers.facebooklive.com/videos/561/big-code-developer-infrastructure-at-facebook-s-scale">Big Code: Developer Infrastructure at Facebook's Scale</a>
  461. talk. This is highly relevant to my job role as Developer Productivity
  462. Engineer at Mozilla.</p>
  463. <p>My notes for this talk follow.</p>
  464. <p><strong>"We don't want humans waiting on computers. We want computers waiting
  465. on humans."</strong> (This is the common theme of the talk.)</p>
  466. <p>In 2005, Facebook was on Subversion. In 2007 moved to Git. Deployed
  467. a bridge so people worked in Git and had distributed workflow but
  468. pushed to Subversion under the hood.</p>
  469. <p>New platforms over time. Server code, iOS, Android. One Git repo
  470. per platform/project -&gt; 3 Git repos. Initially no code sharing, so
  471. no problem. Over time, code sharing between all repos. Lots of code
  472. copying and confusion as to what is where and who owns what.</p>
  473. <p>Facebook is mere weeks away from completing their migration to
  474. consolidate the big three repos to a Mercurial monorepo. (See also
  475. <a href="/blog/2014/09/09/on-monolithic-repositories/">my post about monorepos</a>.)</p>
  476. <p>Reasons:</p>
  477. <ol>
  478. <li>Easier code sharing.</li>
  479. <li>Easier large-scale changes. Rewrite the universe at once.</li>
  480. <li>Unified set of tooling.</li>
  481. </ol>
  482. <p>Facebook employees run &gt;1M source control commands per day. &gt;100k
  483. commits per week. VCS tool needs to be fast to prevent distractions
  484. and context switching, which slow people down.</p>
  485. <p>Facebook implemented sparse checkout and shallow history in Mercurial.
  486. Necessary to scale distributed version control to large repos.</p>
  487. <p><strong>Quote from Google: "We're excited about the work Facebook is doing with
  488. Mercurial and glad to be collaborating with Facebook on Mercurial
  489. development."</strong> (Well, I guess the cat is finally out of the bag:
  490. Google is working on Mercurial. This was kind of an open secret for
  491. months. But I guess now it is official.)</p>
  492. <p>Push-pull-rebase bottleneck: if you rebase and push and someone beats
  493. you to it, you have to pull, rebase, and try again. This gets worse
  494. as commit rate increases and people do needless legwork. <strong>Facebook
  495. has moved to server-side rebasing on push</strong> to mostly eliminate this
  496. pain point. (This is part of a still-experimental feature in Mercurial,
  497. which should hopefully lose its experimental flag soon.)</p>
  498. <p>Starting 13:00 in we have a speaker change and move away from version
  499. control.</p>
  500. <p>IDEs don't scale to Facebook scale. <strong>"Developing in Xcode at Facebook
  501. is an exercise in frustration."</strong> On average 3.5 minutes to open
  502. Facebook for iOS in Xcode. 5 minutes on average to index. Pegs CPU
  503. and makes not very responsive. 50 Xcode crashes per day across all
  504. Facebook iOS developers.</p>
  505. <p><strong>Facebook measures everything about tools. Mercurial operation times.
  506. Xcode times. Build times. Data tells them what tools and workflows
  507. need to be worked on.</strong></p>
  508. <p>Facebook believes IDEs are worth the pain because they make people
  509. more productive.</p>
  510. <p>Facebook wants to support all editors and IDEs since people want to
  511. use whatever is most comfortable.</p>
  512. <p>React Native changed things. Supported developing on multiple
  513. platforms, which no single IDE supports. People launched several
  514. editors and tools to do React Native development. People needed 4
  515. windows to do development. That experience was "not acceptable."
  516. So they built their own IDE. Set of plugins on top of ATOM. Not
  517. a fork. They like hackable and web-y nature of ATOM.</p>
  518. <p>The demo showing iOS development looks very nice! Doing Objective-C,
  519. JavaScript, simulator integration, and version control in one window!</p>
  520. <p>It can connect to remote servers and transparently save and
  521. deploy changes. It can also get real-time compilation errors and hints
  522. from the remote server! (Demo was with Hack. Not sure if others langs
  523. supported. Having beefy central servers for e.g. Gecko development
  524. would be a fun experiment.)</p>
  525. <p>Starting at 32:00 presentation shifts to continuous integration.</p>
  526. <p>Number one goal of CI at Facebook is developer efficiency. <strong>We
  527. don't want developers waiting on computers to build and test diffs.</strong></p>
  528. <p>3 goals for CI:</p>
  529. <ol>
  530. <li>High-signal feedback. Don't want developers chasing failures that
  531. aren't their fault. Wastes time.</li>
  532. <li>Must provide rapid feedback. Developers don't want to wait.</li>
  533. <li>Provide frequent feedback. Developers should know as soon as
  534. possible after they did something. (I think this refers to local
  535. feedback.)</li>
  536. </ol>
  537. <p>Sandcastle is their CI system.</p>
  538. <p>Diff lifecycle discussion.</p>
  539. <p>Basic tests and lint run locally. (My understanding from talking
  540. with Facebookers is "local" often means on a Facebook server, not
  541. local laptop. Machines at developers fingertips are often dumb
  542. terminals.)</p>
  543. <p>They appear to use code coverage to determine what tests to run.
  544. "We're not going to run a test unless your diff might actually have
  545. broken it."</p>
  546. <p>They run flaky tests less often.</p>
  547. <p>They run slow tests less often.</p>
  548. <p><strong>Goal is to get feedback to developers in under 10 minutes.</strong></p>
  549. <p><strong>If they run fewer tests and get back to developers quicker,
  550. things are less likely to break than if they run more tests but
  551. take longer to give feedback.</strong></p>
  552. <p>They also want feedback quickly so reviewers can see results at
  553. review time.</p>
  554. <p>They use Web Driver heavily. Love cross-platform nature of Web Driver.</p>
  555. <p>In addition to test results, performance and size metrics are reported.</p>
  556. <p>They have a "Ship It" button on the diff.</p>
  557. <p>Landcastle handles landing diff.</p>
  558. <p>"It is not OK at Facebook to land a diff without using Landcastle."
  559. (Read: developers don't push directly to the master repo.)</p>
  560. <p>Once Landcastle lands something, it runs tests again. If an issue
  561. is found, a task is filed. Task can be "push blocking."
  562. Code won't ship to users until the "push blocking" issue resolved.
  563. (Tweets confirm they do backouts "fairly aggressively." A valid
  564. resolution to a push blocking task is to backout. But fixing forward
  565. is fine as well.)</p>
  566. <p>After a while, branch cut occurs. Some cherry picks onto release
  567. branches.</p>
  568. <p>In addition to diff-based testing, they do continuous testing runs.
  569. Much more comprehensive. No time restrictions. Continuous runs on
  570. master and release candidate branches. Auto bisect to pin down
  571. regressions.</p>
  572. <p>Sandcastle processes &gt;1000 test results per second. 5 years of machine
  573. work per day. Thousands of machines in 5 data centers.</p>
  574. <p>They started with buildbot. Single master. Hit scaling limits of
  575. single thread single master. Master could not push work to workers
  576. fast enough. Sandcastle has distributed queue. Workers just pull
  577. jobs from distributed queue.</p>
  578. <p>"High-signal feedback is critical." "Flaky failures erode developer
  579. confidence." "We need developers to trust Sandcastle."</p>
  580. <p>Extremely careful separating infra failures from other failures.
  581. Developers don't see infra failures. Infra failures only reported
  582. to Sandcastle team.</p>
  583. <p>Bots look for flaky tests. Stress test individual tests. Run tests
  584. in parallel with themselves. Goal: developers don't see flaky tests.</p>
  585. <p>There is a "not my fault" button that developers can use to report
  586. bad signals.</p>
  587. <p><strong>"Whatever the scale of your engineering organization, developer
  588. efficiency is the key thing that your infrastructure teams should be
  589. striving for. This is why at Facebook we have some of our top
  590. engineers working on developer infrastructure."</strong> (Preach it.)</p>
  591. <p>Excellent talk. <strong>Mozillians doing infra work or who are in charge
  592. of head count for infra work should watch this video.</strong></p>
  593. <p><em>Update 2015-03-28 21:35 UTC - Clarified some bits in response to
  594. new info Tweeted at me. Added link to my monorepos blog post.</em></p>
  595. </article>
  596. </section>
  597. <nav id="jumpto">
  598. <p>
  599. <a href="/david/blog/">Accueil du blog</a> |
  600. <a href="http://gregoryszorc.com/blog/2015/03/28/notes-from-facebook%27s-developer-infrastructure-at-scale-f8-talk/">Source originale</a> |
  601. <a href="/david/stream/2019/">Accueil du flux</a>
  602. </p>
  603. </nav>
  604. <footer>
  605. <div>
  606. <img src="/static/david/david-larlet-avatar.jpg" loading="lazy" class="avatar" width="200" height="200">
  607. <p>
  608. Bonjour/Hi!
  609. Je suis <a href="/david/" title="Profil public">David&nbsp;Larlet</a>, je vis actuellement à Montréal et j’alimente cet espace depuis 15 ans. <br>
  610. Si tu as apprécié cette lecture, n’hésite pas à poursuivre ton exploration. Par exemple via les <a href="/david/blog/" title="Expériences bienveillantes">réflexions bimestrielles</a>, la <a href="/david/stream/2019/" title="Pensées (dés)articulées">veille hebdomadaire</a> ou en t’abonnant au <a href="/david/log/" title="S’abonner aux publications via RSS">flux RSS</a> (<a href="/david/blog/2019/flux-rss/" title="Tiens c’est quoi un flux RSS ?">so 2005</a>).
  611. </p>
  612. <p>
  613. Je m’intéresse à la place que je peux avoir dans ce monde. En tant qu’humain, en tant que membre d’une famille et en tant qu’associé d’une coopérative. De temps en temps, je fais aussi des <a href="https://github.com/davidbgk" title="Principalement sur Github mais aussi ailleurs">trucs techniques</a>. Et encore plus rarement, <a href="/david/talks/" title="En ce moment je laisse plutôt la place aux autres">j’en parle</a>.
  614. </p>
  615. <p>
  616. Voici quelques articles choisis :
  617. <a href="/david/blog/2019/faire-equipe/" title="Accéder à l’article complet">Faire équipe</a>,
  618. <a href="/david/blog/2018/bivouac-automnal/" title="Accéder à l’article complet">Bivouac automnal</a>,
  619. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  620. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  621. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  622. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  623. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  624. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  625. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  626. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  627. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  628. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  629. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  630. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  631. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  632. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  633. </p>
  634. <p>
  635. On peut <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">échanger par courriel</a>. Si éventuellement tu souhaites que l’on travaille ensemble, tu devrais commencer par consulter le <a href="http://larlet.com">profil dédié à mon activité professionnelle</a> et/ou contacter directement <a href="http://scopyleft.fr/">scopyleft</a>, la <abbr title="Société coopérative et participative">SCOP</abbr> dont je fais partie depuis six ans. Je recommande au préalable de lire <a href="/david/blog/2018/cout-site/" title="Attention ce qui va suivre peut vous choquer">combien coûte un site</a> et pourquoi je suis plutôt favorable à une <a href="/david/pro/devis/" title="Discutons-en !">non-demande de devis</a>.
  636. </p>
  637. <p>
  638. Je ne traque pas ta navigation mais mon
  639. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">hébergeur</abbr>
  640. conserve des logs d’accès.
  641. </p>
  642. </div>
  643. </footer>
  644. <script type="text/javascript">
  645. ;(_ => {
  646. const jumper = document.getElementById('jumper')
  647. jumper.addEventListener('click', e => {
  648. e.preventDefault()
  649. const anchor = e.target.getAttribute('href')
  650. const targetEl = document.getElementById(anchor.substring(1))
  651. targetEl.scrollIntoView({behavior: 'smooth'})
  652. })
  653. })()
  654. </script>