William Lachance's Log: William Lachance's Logurn:https-wrla-ch:-index-html2023-04-15T14:33:52ZNeural networks mystify meurn:https-wrla-ch:-blog-2023-04-neural-networks-mystify-me2023-04-15T14:33:52Z2023-04-15T14:33:52ZWilliam Lachance
<p>Spent a good chunk of a week off (re)learning the basics of neural networks: forward propagation, gradient descent, loss functions. It’s taking some time, but gradually I feel some level of understanding is taking hold. What kind of continues to amaze me is how simple it all is: you really only need a high-school level understanding of linear algebra and calculus to understand most of what’s going on behind the scenes. Best as I can tell, the recent innovations in the last few years (in particular transformer models behind things like ChatGPT) are just refinements on top of these basic concepts.</p>
<p>Neural networks (there really there is nothing “neural” about them) are really not new: I remember hearing about that as an undergraduate in the early 2000s (and I think they were rather old hat even then). At the time, they were pretty much dismissed as a warmed-over model of <a href="https://en.wikipedia.org/wiki/Behaviorism">behaviorism</a>, unlikely to be useful anywhere except perhaps in a few simplistic applications. Based on what I saw at the time, I agreed and basically bought into the idea that computers are mainly useful as an adjunct to human processes, systems and intuition.</p>
<p>Thus, I find the fact that these systems can produce something even mildly resembling novel or creative outputs (as is the case with things like ChatGPT and Midjourney) <em>surprising</em> - as in it wasn’t something I saw coming. Yes, much of what has been built using these technologies is overhyped and arguably dangerous. Still, I also don’t want to lose the sense of wonder that this is possible at all. If I was mistaken about this what else might I be missing?</p>
<p>I feel like the best response at this point is to take a step back, learn as much as I can, and <em>then</em> develop an opinion. I expect this process to take at least a year, probably longer.</p>
<p>In case it’s helpful to others, here’s some literature I’ve been working through on these topics.</p>
<p>Some theoretical but approachable material for understanding the basics:</p>
<ul>
<li><a href="http://karpathy.github.io/neuralnets/">Hacker’s Guide to Neural Networks</a>: Now dislcaimed by the author as out of date, I still found its explanation of neural networks as a circuit quite helpful for building my intuition.</li>
<li><a href="http://neuralnetworksanddeeplearning.com/index.html">Neural Networks and Deep Learning</a>: Another introduction to the basics, more refined and comprehensive than the above.</li>
<li><a href="https://codewords.recurse.com/issues/five/why-do-neural-networks-think-a-panda-is-a-vulture">How to trick a neural network into thinking a panda is a vulture</a>: Often the best way of understanding something is to break it.</li></ul>
<p>On the ethical side:</p>
<ul>
<li><a href="https://dl.acm.org/doi/10.1145/3442188.3445922">On the Dangers of Stochastic Parrots</a>: Good antidote to some of the hype around LLMs, incorporating an understanding of how these systems may further perpetuate social harms. Much more nuanced and interesting than most of the critiques I’ve seen fly by in the last few months.</li>
<li><a href="https://zephoria.medium.com/resisting-deterministic-thinking-52ef8d78248c">Resisting Determinstic Thinking</a>: How can we think critically about AI without falling into the trap of black/white thinking (“this is all good” vs. “this is all bad”)</li></ul>
<p>And some articles on how to think about LLMs from a pragmatic perspective as a programmer:</p>
<ul>
<li><a href="https://simonwillison.net/2023/Apr/2/calculator-for-words/">Think of language models like ChatGPT as a “calculator for words”</a>: This feels right to me based on my usage of OpenAI as a “tool for thought so far” (though I don’t think I’ve yet been able to use ChatGPT as effectively as this person).</li>
<li><a href="https://about.sourcegraph.com/blog/cheating-is-all-you-need">Cheating is all you need</a>: Some speculative thinking about how this stuff might play out for those of us doing programming from the internet-famous Steve Yegge.</li></ul>Working with depressionurn:https-wrla-ch:-blog-2022-11-working-with-depression2022-11-26T15:24:01Z2022-11-26T15:24:01ZWilliam Lachance
<p>Been struggling with depression over the past couple of weeks. Some of this is seasonal (with the shortening of the days), though I wouldn’t say it <em>always</em> happens. Last year at this time I recall feeling the <em>opposite</em> of depressed: that probably had to do with the fact that I knew I was leaving my previous job at Mozilla and wanted to get as much done as possible. Sometimes a highly motivating life situation can keep it in abeyance. Nonetheless, it’s here now, again, and demands to be dealt with.</p>
<p>What does depression even mean? It’s a bit of a hard thing to pin down, exactly. But from the perspective of looking after my own well being, I don’t think I really need a definition. What matters are the symptoms, which I’d roughly express as:</p>
<ul>
<li>Knowing what I <em>should</em> be doing but not able to do it</li>
<li>An increase in time spent scanning social media, news sites</li>
<li>Feelings of low self worth</li>
<li>Feelings that nothing really matters</li>
<li>Lack of creativity, improvisation</li>
<li>An increase in self-referential thinking (this post would be an example of that)</li></ul>
<p>A few things I tend to try to diminish its effects:</p>
<ul>
<li>Go outside, expose myself to sunlight. Explore nature.</li>
<li>Exercise</li>
<li>Meditate</li>
<li>Eat less carbohydrates, more vegetables and protein</li>
<li>Talk to friends</li>
<li>Do nice things for other people</li></ul>
<p>I don’t feel like doing these things but I try with all my might, against all my will, to do them anyway. Any individual action might not do much: but the cumulative effect of doing <em>all</em> of the above seems to have an impact — or at least that’s what I tell myself.</p>
<p>And yet despite my best efforts, it’s not always enough. I do all of the things in the second list, and yet still find myself suffering in all the ways described by the first. What do I do then?</p>
<p>I try to understand that there really isn’t an escape from unpleasant feeling, and that it’s just part of life: glorious and beautiful in its complexity. I try to be <em>curious</em> about what’s going on, even if I think it’s all happened before. If that’s not possible, I at least try to be present with it. That’s all I can do.</p>Using Sphinx in a Monorepourn:https-wrla-ch:-blog-2022-09-using-sphinx-in-a-monorepo2022-09-25T19:55:40Z2022-09-25T19:55:40ZWilliam Lachance
<p>Just wanted to type up a couple of notes about working with <a href="https://www.sphinx-doc.org/en/master/">Sphinx</a> (the python documentation generator) inside a monorepo, an issue I’ve been struggling with (off and on) at <a href="https://voltus.co">Voltus</a> since I started. I haven’t seen much written about this topic despite (I suspect) it being a reasonably frequent problem.</p>
<p>In general, there’s a lot to like about Sphinx: it’s great at handling deeply nested trees of detailed documentation with cross-references inside a version control system. It has local search that works pretty well and some themes (like <a href="https://sphinx-rtd-theme.readthedocs.io/en/stable/">readthedocs</a>) scale pretty nicely to hundreds of documents. The directives and roles system is pretty flexible and covers most of the common things one might want to express in technical documentation. And if the built-in set of functionality isn’t enough, there’s a wealth of third party extension modules. My only major complaint is that it uses the somewhat obscure <a href="https://docutils.sourceforge.io/rst.html">restructuredText</a> file format by default, but you can get around that by using the excellent <a href="https://myst-parser.readthedocs.io/en/latest/">MyST extension</a>.</p>
<p>Unfortunately, it has a pretty deeply baked in assumption that all documentation for your project lives inside a <em>single</em> subfolder. This is fine for a small repository representing a single python module, like this:</p>
<pre><code><root>
README.md
setup.cfg
pyproject.toml
mymodule/
docs/</code></pre>
<p>However, this doesn’t work for a large monorepo, where you would typically see something like:</p>
<pre><code><root>/module-1/submodule-a
<root>/module-1/submodule-b
<root>/module-2/submodule-c
...</code></pre>
<p>In a monorepo, you usually want to include a module’s documentation inside its own directory. This allows you to use your <a href="https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners">code ownership constraints</a> for documentation, among other things.</p>
<p>The naive solution would be to create a sphinx site for every single one of these submodules. This is what happened at Voltus and I don’t recommend it. For a large monorepo you’ll end up with dozens, maybe hundreds of documentation “sites”. Under this scenario, discoverability becomes a huge problem: no longer can you rely on tables of contents and the built-in search to discover content: you just have to “know” where things live. I’m more than nine months in here and I’m <em>still</em> discovering new documentation.</p>
<p>It would be much better if we could somehow collect documentation from other parts of the repository into a single site. Is this possible? tl;dr: Yes. There’s a few solutions, each with their pros and cons.</p>
<h2 id="the-obvious-solution-that-doesnt-work">The obvious solution that doesn’t work</h2>
<p>The most obvious solution here is to create a symbolic link inside your documentation directory, say the following:</p>
<pre><code><root>/docs/
<root>/docs/module-1/submodule-a -> <root>/module-1/submodule-a/docs</code></pre>
<p>Unfortunately, <a href="https://stackoverflow.com/questions/10199233/can-sphinx-link-to-documents-that-are-not-located-in-directories-below-the-root">this doesn’t work</a>. ☹️ Sphinx doesn’t follow symbolic links.</p>
<h2 id="solution-1-just-copy-the-files-in">Solution 1: Just copy the files in</h2>
<p>The most obvious solution is to just copy the files from various parts of the monorepo into place, as part of the build system. Mozilla did this for Firefox, with the <a href="https://searchfox.org/mozilla-central/source/tools/moztreedocs/__init__.py">moztreedocs</a> system.</p>
<p>The <a href="https://firefox-source-docs.mozilla.org/">results look pretty good</a>, but this is a bespoke solution. Aside from general ideas, there’s no way I’m going to be able to apply anything in moztreedocs to Voltus’s monorepo (which is based on a completely different build system). And being honest, I’m not sure if the 40+ hour (estimated) effort to reimplement it would be a good use of time compared to other things I could be doing.</p>
<h2 id="solution-2-use-the-include-directive-with-myst">Solution 2: Use the include directive with MyST</h2>
<p>Later versions of MyST include support for <a href="https://myst-parser.readthedocs.io/en/latest/faq/index.html#include-a-file-from-outside-the-docs-folder-like-readme-md">directly importing a markdown file from another part of the repository</a>.</p>
<p>This is a limited form of embedding: it won’t let you import an entire directory of markdown files. But if your submodules mostly just include content in the form of a <code>README.md</code> (or similar), it might just be enough. Just create a directory for these files to live (say <code>services</code>) and slot them in:</p>
<p><code><root>/docs/services/module-1/submodule-a/index.md</code>:</p>
<pre><code>```{include} ../../../module-1/submodule-a/README.md
```</code></pre>
<p>I’m currently in the process of implementing this solution inside Voltus. I have optimism that this will be a big (if incremental) step up over what we have right now. There are obviously limits, but you can cram a lot of useful information in a README. As a bonus, it’s a pretty nice marker for those spelunking through the source code (much more so than a forest of tiny documentation files).</p>
<h2 id="solution-3-sphinx-collections">Solution 3: Sphinx Collections</h2>
<p>This one I just found about today: <a href="https://sphinx-collections.readthedocs.io">Sphinx Collections</a> is a small python module that lets you automatically import entire <em>directories</em> of files into your sphinx tree, under a <code>_collections</code> module. You configure it in your top-level <code>conf.py</code> like this:</p>
<div class="brush: py">
<div class="colorful">
<pre><span></span><span class="n">extensions</span> <span class="o">=</span> <span class="p">[</span>
<span class="o">...</span>
<span class="s2">"sphinxcontrib.collections"</span>
<span class="p">]</span>
<span class="n">collections</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">"submodule-a"</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">"driver"</span><span class="p">:</span> <span class="s2">"symlink"</span><span class="p">,</span>
<span class="s2">"source"</span><span class="p">:</span> <span class="s2">"/monorepo/module-1/submodule-a/docs"</span><span class="p">,</span>
<span class="s2">"target"</span><span class="p">:</span> <span class="s2">"submodule-a"</span>
<span class="p">},</span>
<span class="o">...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>After setting this up, <code>submodule-a</code> is now available under <code>_collections</code> and you can include it in your table of contents like this:</p>
<pre><code>...
```{toctree}
:caption: submodule-a
_collections/submodule-a/index.md
```
...</code></pre>
<p>At this point, <code>submodule-a</code>’s documentation should be available under <code>http://<my doc domain>/_collections/submodule-a/index.html</code></p>
<p>Pretty nifty. The main downside I’ve found so far is that this doesn’t play nicely with the <a href="https://docs.readthedocs.io/en/stable/guides/edit-source-links-sphinx.html">Edit on GitHub</a> links that the readthedocs theme automatically inserts (it thinks the files exist under <code>_collections</code>), but there’s probably a way to work around that.</p>
<p>I plan on investigating this approach further in the coming months.</p>90 days out and inurn:https-wrla-ch:-blog-2022-04-90-days-out-and-in2022-04-16T16:44:14Z2022-04-16T16:44:14ZWilliam Lachance
<p>The 90 day mark just passed at my <a href="https://voltus.co">new gig at Voltus</a>, feels like a good time for a bit of self-reflection.</p>
<p>In general, I think it’s been a good change and that it was the right time to leave Mozilla. Since I left, a few people have asked me why I chose to do so: while the full answer is pretty complicated (these things are never simple!), I think it does ultimately come down to wanting to try something new after 10+ years. I’ve accumulated a fair amount of expertise in web development and data engineering and I wanted to see if I could apply them to a new area that I cared about— in this case, climate change and the energy transition.</p>
<p>Voltus is a much younger and different company than Mozilla was, and there’s no shortage of things to learn and do. Energy markets are a rather interesting technical domain to work in— a big intersection between politics, technology, and business. Lots of very old and very new things all at once. As a still-relatively young company, there is definitely more of a feeling that it’s possible to shape Voltus’s culture and practices, which has been interesting. There’s a bit of a balancing act between sharing what you’ve learned in previous roles while having the humility to recognize that there’s much you still don’t understand in a new workplace.</p>
<p>On the downside, I have to admit that I do miss being able to work in the open. <a href="https://www.canarymedia.com/articles/climatetech-finance/voltus-launches-1-3b-spac-to-help-businesses-reshape-their-power-use-and-ease-grid-stress">Voltus is currently in the process of going public</a>, which has made me extra shy about saying much of anything about what I’ve been working on in a public forum.</p>
<p>To some extent I’ve been scratching this itch by continuing to work on <a href="https://irydium.dev">Irydium</a> when I have the chance. I’ve done up a few new releases in the last couple of months, which I think have been fairly well received inside my very small community of people doing like-minded things. I’m planning on attending (at least part of) a <a href="https://github.com/pyodide/pyodide/wiki/PyCon2022-sprint">pyodide sprint</a> in early May, which I think should be a lot of fun as well as an opportunity to push browser-based data science forward.</p>
<p>I’ve also kept more of a connection with Mozilla than I thought I would have: some video meetings with former colleagues, answering questions on Element (<a href="https://wiki.mozilla.org/Matrix">chat.mozilla.org</a>), even <a href="https://github.com/mozilla/glean-dictionary/pulls?q=is%3Apr+author%3Awlach+is%3Aclosed">some pull requests</a> where I felt like I could make a quick contribution. I’m still using Firefox, which has actually given me more perspective on some problems that people at Mozilla might not experience (e.g. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1536777">this screensharing bug</a> which you’d only see if you’re using a WebRTC-based video conferencing solution like Google Meet).</p>
<p>That said, I’m not sure to what extent this will continue: even if the source code to Firefox and the tooling that supports it is technically “open source”, outsiders like myself really have very limited visibility into what Mozilla is doing these days. This makes it difficult to really connect with much of what’s going on or know how I might be able to contribute. While it might be theoretically possible to join Mozilla’s Slack (at least last I checked), that feels like a rabbit hole I’d prefer not to go down. While I’m still interested in supporting Mozilla’s mission, I really don’t want more than one workplace chat tool in my life: there’s a lot of content there that is no longer relevant to me as a non-employee and (being honest) I’d rather leave behind. There’s lots more I could say about this, but probably best to leave it there: I understand that there’s reasons why things are the way they are, even if they make me a little sad.</p>Leaving Mozillaurn:https-wrla-ch:-blog-2021-12-leaving-mozilla2021-12-21T18:43:09Z2021-12-21T18:43:09ZWilliam Lachance
<p>I’ve decided to leave Mozilla as an employee: my last day will be December 31st, 2021.</p>
<p>It’s hard to overstate the impact Mozilla has had on my life. In particular, I’m grateful for all the interactions I’ve had with the community: the opportunity to build technology for the public good with people around the world was unique and I’m really going to miss it.</p>
<p>Looking back over the <a href="/blog/2021/07/10-years-at-mozilla/">past 10 years</a>, I’m feeling pretty good about the impact I had through building better developer and data tooling: <a href="https://mozilla.github.io/mozregression">mozregression</a>, <a href="https://wiki.mozilla.org/EngineeringProductivity/Projects/Perfherder">Perfherder</a>, <a href="https://github.com/iodide-project/iodide">Iodide</a> and the <a href="https://dictionary.telemetry.mozilla.org">Glean Dictionary</a> stand out as particular highlights. Thanks to everyone who worked on those things with me! I am because we are.</p>
<h2 id="last-lecture">Last Lecture</h2>
<p>It’s become traditional in <a href="https://wiki.mozilla.org/Data">Data @ Mozilla</a> for the person leaving to give a last lecture on their way out. I decided to give a talk on a specific area of focus for me over the last couple of years: <a href="https://docs.telemetry.mozilla.org">documentation</a>.</p>
<iframe width="600" height="400" src="https://www.youtube.com/embed/E5j6BoxZ-7w" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="allowfullscreen"></iframe>
<p>I’m not sure how comprehensible it will be to people outside of my particular context at Mozilla, but it seemed fitting to post it publically regardless.</p>
<p>I’m more convinced than ever that documentation is one of the keys to empowering people to make better decisions with data (no matter what their job title). I hope my efforts here have been helpful.</p>
<h2 id="joining-the-community">Joining the Community</h2>
<p>After having spent a good chunk of energy on making it possible for people outside the Mozilla Corporation to contribute to our projects, I’m looking forward to seeing what it’s like on the other side of the fence.</p>
<p>I’m not sure right now exactly how active I’ll be, but I plan on sticking around on Matrix and Bugzilla, at least a little bit. If there’s anything I can help you with, feel free to reach out!</p>Learning about Psychological Safety at the Recurse Centerurn:https-wrla-ch:-blog-2021-10-learning-about-psychological-safety-at-the-recurse-center2021-10-19T12:34:40Z2021-10-19T12:34:40ZWilliam Lachance
<p>Last summer, I took a 6-week sabbatical from my job to attend a virtual “programmers retreat” at the <a href="https://recurse.com">Recurse Center</a>. I thought I’d write up some notes on the experience, with a particular lens towards what makes an environment suited towards learning, innovation, and personal growth.</p>
<p>Some context: I’m currently working as a software engineer at Mozilla, building out our data pipeline and analysis tooling. I’ve been at my current position for more than 10 years (my “anniversary” actually passed while I was out). I started out as a senior engineer in 2011, and was promoted to staff engineer in 2016. In tech-land, this is a really long tenure at a company. I felt like it was time to take a break from my day-to-day, explore some new ideas and concepts, and hopefully expose myself to a broader group of people in my field.</p>
<p>My original thinking was that I would mostly be spending this time building out an interactive computation environment I’ve been working on called <a href="https://irydium.dev">Irydium</a>. And I did quite a bit of that. However, I think the main thing I took away from this experience was some insight on what makes a remote environment for knowledge work really “click”. In particular, what makes somewhere feel psychologically safe, and how this feeling allows us to innovate and do our best work.</p>
<p>While the Recurse Center obviously has different goals than an organization that builds and delivers consumer software, I do think there are some things that it does that could be applied to Mozilla (and, likely, many other tech workplaces).</p>
<h2 id="what-is-the-recurse-center">What is the Recurse Center?</h2>
<p>Most succinctly, the Recurse Center is a “writer’s retreat for programmers”. It tries to provide an environment conducive to learning and creativity, an opportunity to refine your craft and learn new things, both from the act of programming itself <em>and</em> from interactions with the other like-minded people attending. The Recurse Center admits a wide variety of people, from those who have only been through a coding bootcamp to those who have been in the industry many years, like myself. The main admission criteria, from what I gather, are curiosity and friendliness.</p>
<p>Once admitted, you do a “batch”— either a mini (1 week), half-batch (6 weeks), or a full batch (12 weeks). I did a half-batch.</p>
<h2 id="how-does-it-work-during-a-global-pandemic">How does it work (during a global pandemic)?</h2>
<p>The Recurse experience used to be entirely in-person, in a space in New York City - if you wanted to go, you needed to move there at least temporarily. Obviously that’s out the window during a Global Pandemic, and all activities are currently happening online. This was actually pretty ideal for me at this point in my life, as it allowed me to participate entirely remotely from my home in Hamilton, Ontario, Canada (near Toronto).</p>
<p>There’s a few elements that make “Virtual RC” tick:</p>
<ul>
<li>A virtual space (pictured below) where you can see other people in your cohort. This is particularly useful when you want to jump into a conference room.</li>
<li>A shared “calendar” where people can schedule events, either adhoc (e.g. a one off social event, discussing a paper) or on a regular basis (e.g. a reading group)</li>
<li>A zulip chat server (which is a bit like Slack) for adhoc conversation with people in your cohort and alumni. There are multiple channels, covering a broad spectrum of interests.</li></ul>
<div class="figure"><img src="/files/2021/10/virtual_RC.png" alt="" />
<p class="caption"></p></div>
<h2 id="why-does-it-work">Why does it work?</h2>
<p>So far, what I’ve described probably sounds a lot like any remote tech workplace during the pandemic… and it sort of is! In some ways, my schedule and life while at Recurse didn’t feel all that different from my normal day-to-day. Wake up in the morning, drink coffee, meditate, work for roughly 8 hours, done. Qualitatively, however, my experience at Recurse felt unusually productive, and I learned a lot more than I expected to: not just the core stuff related to Irydium, but also unexpected new concepts like CRDTs, product design, and even <a href="https://github.com/microsoft/vscode-textmate/issues/152">how visual studio code syntax highlighting works</a>.</p>
<p>What made the difference? Certainly, not having the normal pressures of a workplace helps - but I think there’s more to it than that. The way RC is constructed reinforces a sense of <em>psychological safety</em> which I think is key to learning and growth.</p>
<h2 id="what-is-psychological-safety-and-why-should-i-care">What is psychological safety and why should I care?</h2>
<p>Psychological safety is a bit of a hot topic these days and there’s a lot of discussion about in management circles. I think it comes down to a feeling that you can take risks and “put yourself out there” without fear that you’ll be ignored, attacked, or ridiculed.</p>
<p>Why is this important? I would argue, because knowledge work is about building understanding — going from a place of not understanding to understanding. If you’re working on anything at all innovative, there is always an element of the unknown. In my experience, there is virtually always a sense of discomfort and uncertainty that goes along with that. This goes double when you’re working around and with people that you don’t know terribly well (and who might have far more experience than you). Are they going to make fun of you for not knowing a basic concept or for expressing an idea that’s “so wrong I don’t even know where to begin”? Or, just as bad, will you not get any feedback on your work at all?</p>
<p>In reality, except in truly toxic environments, you’ll rarely encounter outright abusive behaviour. But the isolation of remote work can breed similar feelings of disquiet and discomfort over time. My sense, after a year of working “hardcore” remote in COVID times, is that our normal workplace rituals of meetings, “stand ups”, and discussions over Slack don’t provide enough space for a meaningful sense of psychological safety to develop. They’re good enough for measuring progress towards agreed-upon goals but a true sense of belonging depends on less tightly scripted interactions among peers.</p>
<h2 id="how-the-recurse-environment-creates-psychological-safety">How the Recurse environment creates psychological safety</h2>
<p>But the environment I described above isn’t <em>that</em> different from a workplace, is it? Speaking from my own experience, my coworkers at Mozilla are all pretty nice people. There’s also many channels for informal discussion at Mozilla, and of course direct messaging is always available (via Slack or Matrix). And yet, I still feel there is a pretty large gap between the two experiences. So what makes the difference? I’d say there were three important aspects of Recurse that really helped here: social rules, gentle prompts, and a closed space.</p>
<h3 id="social-rules">Social rules</h3>
<p>There’s been a lot of discussion about community participation guidelines and standards of behaviour in workplaces. In general, these types of policies target really egregious behaviour like harassment: this is a pretty low bar. They aren’t, in my experience, sufficient to actually create an environment that actually feels safe.</p>
<p>The Recurse Center goes over and above a basic code of conduct, with four simple social rules:</p>
<ul>
<li>No well-actually’s: corrections that aren’t relevant to the point someone was trying to make (this is probably the rule we’re most heavily conditioned to break).</li>
<li>No feigned surprise: acting surprised when someone doesn’t know something.</li>
<li>No backseat driving: lobbing advice from across the room (or across the online chat) without really joining or engaging in a conversation.</li>
<li>No subtle -isms: subtle expressions of racism, sexism, ageism, homophobia, transphobia and other kinds of bias and prejudice.</li></ul>
<p>These rules aren’t “commandments” and you’re not meant to feel shame for violating them. The important thing is that by being there, the rules create an <em>environment conducive to learning and growth</em>. You can be reasonably confident that you can bring up a question or discussion point (or respond to one) and it won’t lead to a bad outcome. For example, you can expect not to be made fun of for asking what a UNIX socket is (and if you are, you can tell the person doing so to stop). Rather than there being an unspoken rule that everyone should already know everything about what they are trying to do, there is a spoken rule that states it’s expected that they don’t.</p>
<p>Working on Irydium, there’s an infinite number of ways I can feel incompetent: this is a requirement when engaging with concepts that I still don’t feel completely comfortable with: parsers, compilers, WebAssembly… the list goes on. Knowing that I could talk about what I’m working on (or something I’m interested in) and that the responses I got would be constructive and directed to the project, not the person made all the difference.<sup><a href="#2021-10-19-learning-about-psychological-safety-at-the-recurse-centre-footnote-1-definition" name="2021-10-19-learning-about-psychological-safety-at-the-recurse-centre-footnote-1-return">1</a></sup></p>
<h3 id="gentle-prompts">Gentle prompts</h3>
<p>The thing I loved the most about Recurse were the gentle prompts to engage with other people, talk about your work, and get help. A few that I really enjoyed during my time there:</p>
<ul>
<li>The “checkins” channel. People would post what’s going on with their time at RC, their challenges, their struggles. Often there would be little snippits about people’s lives in there, which built to a feeling of community.</li>
<li>Hack & Tell: A weekly event where a group of us would get together in a Zoom room, talk about working on or building something, then rejoin the chat an hour later to show off what we accomplished.</li>
<li>Coffee Chats: A “coffee chat” bot at RC would pair you with other people in your batch (or alumni) on a cadence of your choosing. I met so many great people this way!</li>
<li>Weekly Presentations: At the end of each week, people would sign up to share something that they were working on our learned.</li></ul>
<p>… and I could go on. What’s important are not the specific activities, but their end effect of building connectedness, creating opportunities for serendipitous collaboration and interaction (more than one discussion group came out of someone’s checkin post on Zulip) and generally creating an environment well-suited to learning.</p>
<h3 id="a-semi-closed-space">A (semi) closed space</h3>
<p>One of the things that makes the gentle prompts above “work” is that you have some idea of who you’re going to be interacting with. Having some predictability about who’s going to see what you post and engage with you (that they were vetted by RC’s interview process and are committed to the above-mentioned social rules) gives you some confidence to be vulnerable and share things that you might be reluctant to otherwise.</p>
<p>Those who have known me for a while will probably see the above as being a bit of departure from what I normally preach: throughout my tenure at Mozilla, I’ve constantly pushed the people I’ve worked with to do more work in public. In the case of a product like Firefox, which touches so many people, I think open and transparent practices are absolutely essential to building trust, creating opportunity, and ensuring that our software reflects a diversity of views. I applied the same philosophy to Irydium’s development while I was at the Recurse Center: I set up a public Matrix channel to discuss the project, published all my work on GitHub, and was quite chatty about what I was working on, both in this blog and on Twitter.</p>
<p>The key, I think, is being deliberate about what approach you take when: there is a place for both public and private conversations about what we work on. I’m strongly in favour of open design documents, community calls, public bug trackers and open source in general. But I think it’s also pretty ok to have smaller spaces for learning, personal development, and question asking. I know I strongly appreciated having a smaller group of people that I could talk to about ideas that were not yet fully formed: you can always bring them out into the open later. The psychological risk of working in public can be mitigated by the psychological safety that can be developed within an intentional community.</p>
<h2 id="bringing-it-back">Bringing it back</h2>
<p>Returning to my job, I wondered if it might be possible to bring some of what I described above back to Mozilla? Obviously not everything would be directly transferable: Mozilla has its own mission and goals, and there are pressures that exist in a workplace that do not exist in an environment purely directed at learning. Still, I suspected that there was something we could do here. And that it would be worth doing, not just to improve the felt experience of the people here (though that would be reason enough) but also to get more feedback on our work and create more opportunities for collaboration and innovation.</p>
<p>I felt like trying to do something inside our particular organization (Data Engineering and Data Science) would be the most tractable initial step. I talked a bit about my experience with <a href="https://bluesock.org/~willkg/">Will Kahn-Green</a> (who has been at Mozilla around the same length of time as I have) and we came up with what we called the “Data Neighbourhood” project: a set of grassroots micro-initiatives to increase our connectedness as a group. As an organization directed primarily at serving other parts of Mozilla, most of our team’s communication is directed outward. It’s often hard to know what everyone else is up to, where they’re struggling, and how we could help each other out. Attacking that problem directly seemed like the best place to start.</p>
<p>The first experiment we tried was a “data checkins” channel on Slack, a place for people to talk informally about their work (or life!). I explicitly set it up with a similar set of social rules as outlined above and tried to emphasize that it was a place to talk about how things are going, rather than a place to report status to your manager. After a somewhat slow start (the initial posts were from Will, myself, and a few other people from Data Engineering who had been around for a long time) we’re beginning to see engagement from others, including some newer people I hadn’t interacted with much before. There’s also been a few useful threads of conversations across different sub-teams (for example, a discussion on how we identify distinct versions of Firefox for iOS) that likely would not have happened without the channel.</p>
<p>Since then, others have tried a few other things in the same vein (an adhoc coffee chat pairing bot, a “writing help” channel) and there are some signs of success. There’s clearly an appetite for new and better ways for us to relate to each other about the work we’re doing, and I’m excited to see how these ideas evolve over time.</p>
<p>I suspect there are limits to how psychologically safe a workplace can ever feel (and some of that is probably outside of any individual’s control). There are dynamics in a workplace which make applying some of Recurse’s practices difficult. In particular, a posture of “not knowing things is o.k.” may not apply perfectly to a workplace where people are hired (and promoted) based on perceived competence and expertise. Still, I think it’s worth investigating what might be possible within the constraints of the system we’re in. There are big potential benefits, for our creative output and our well-being.</p>
<p><em>Many thanks to Jenny Zhang, Kathleen Beckett, Joe Trellick, Taylor Phebillo and Vaibhav Sagar, and Will Kahn-Greene for reviewing earlier drafts of this post</em></p>
<div class="footnotes">
<ol>
<li id="2021-10-19-learning-about-psychological-safety-at-the-recurse-centre-footnote-1-definition" class="footnote-definition">
<p>This is generally considered best practice inside workplaces as well. For example, see <a href="https://google.github.io/eng-practices/review/reviewer/comments.html">Google’s guide on how to write code review comments</a>. <a href="#2021-10-19-learning-about-psychological-safety-at-the-recurse-centre-footnote-1-return">↩</a></p></li></ol></div>Python dependency gotchas: always go to the sourceurn:https-wrla-ch:-blog-2021-08-python-dependency-gotchas-always-go-to-the-source2021-08-16T20:06:09Z2021-08-16T20:06:09ZWilliam Lachance
<p>Getting back into the swing of things at Mozilla after my extended break. I’m currently working on enhancing and extending <a href="https://looker.com/">Looker</a> support for Glean-based applications, which eventually led me back to working on <a href="https://mozilla.github.io/bigquery-etl/">bigquery-etl</a>, our framework for creating derived datasets in our data lake.</p>
<p>I spent some time working on improving the initial developer experience of bigquery-etl early this year, so I figured it would be no problem to get going again despite an extended hiatus from it (I think it’s probably been ~2–3 months since I last touched it). Unfortunately the first thing I got after creating a fresh virtual environment (to pick up the new dependency updates) was this exciting looking error:</p>
<pre><code>wlach@antwerp bigquery-etl % ./bqetl --help
Traceback (most recent call last):
...
File "/Users/wlach/src/bigquery-etl/venv/lib/python3.9/site-packages/google/cloud/bigquery_v2/types/__init__.py", line 16, in <module>
from .encryption_config import EncryptionConfiguration
File "/Users/wlach/src/bigquery-etl/venv/lib/python3.9/site-packages/google/cloud/bigquery_v2/types/encryption_config.py", line 26, in <module>
class EncryptionConfiguration(proto.Message):
File "/Users/wlach/src/bigquery-etl/venv/lib/python3.9/site-packages/proto/message.py", line 200, in __new__
file_info = _file_info._FileInfo.maybe_add_descriptor(filename, package)
File "/Users/wlach/src/bigquery-etl/venv/lib/python3.9/site-packages/proto/_file_info.py", line 42, in maybe_add_descriptor
descriptor=descriptor_pb2.FileDescriptorProto(
TypeError: descriptor to field 'google.protobuf.FileDescriptorProto.name' doesn't apply to 'FileDescriptorProto' object</code></pre>
<h2 id="what-i-did">What I did</h2>
<p>Since we have pretty decent continuous integration at Mozilla, when I see an error like this I am usually pretty sure it’s some kind of strange interaction between my local development environment and whatever dependencies we’ve specified for the repository in question. Usually these problems are pretty easy to solve.</p>
<p>First thing I tried was to type the error into Google, to see if this had come up for anyone else before. I tried several variations of <code>TypeError: descriptor to field</code> and <code>FileDescriptorProto</code> and nothing really turned up. This strategy almost always turns up <em>something</em>. When it doesn’t it usually indicates that something pretty strange is happening.</p>
<p>To see if this was a strange problem particular to <em>us</em>, I asked on our internal channel but no one had offhand seen or heard of this error either. One of my colleagues (who had a working setup on a Mac, the same environment I was using) suggested I set up <a href="https://github.com/pyenv/pyenv">pyenv</a> to isolate my development environment, which was a good idea but did not seem to solve the problem: both Python 3.8 and 3.9 installed via pyenv ran into the exact same issue.</p>
<p>After flailing around trying a number of other failed approaches (maybe I need to upgrade the version of virtualenv that we’re using?), I broke down and looked harder at the error itself. It seemed to be some kind of typing error in Google’s protobuf library, which google-cloud-bigquery is calling. If this sort of thing was happening to <em>everyone</em>, we probably would have seen it happening more broadly. So my guess, again, was that it was happening due to an obscure interaction between some variable on my machine and this particular combination of dependencies.</p>
<p>At this point, I systematically went through our set of python dependencies to see what might be the matter. For the most part, I found nothing surprising or suspicious. <code>google-api-core</code> was at the latest version, as was <code>google-cloud-bigquery</code>. However, I <em>did</em> notice that the version of <a href="https://pypi.org/project/protobuf/">protobuf</a> we were using was a little older (3.15.8 when the latest “official” version on pypi was 3.17.3).</p>
<div class="figure"><img src="/files/2021/08/pypi-screenshot.png" alt="" />
<p class="caption"></p></div>
<p>It seemed like a longshot that the problem was there, but it seemed like upgrading the dependency was worth a try just in case. So I bumped the version of protobuf to the latest version in my local checkout (<code>pip install protobuf==3.17.3</code>)…</p>
<p>… and sure enough, after doing so, the problem was fixed and <code>./bqetl --help</code> started working again:</p>
<pre><code>wlach@antwerp bigquery-etl % ./bqetl --help
Usage: bqetl [OPTIONS] COMMAND [ARGS]...
CLI tools for working with bigquery-etl.
...</code></pre>
<p>After doing so, I did up a quick <a href="https://github.com/mozilla/bigquery-etl/pull/2266">pull request</a> and the problem is now fixed, at least for me.</p>
<p>It’s a bit unfortunate that <a href="https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/about-dependabot-version-updates">dependabot</a> (which we have configured for this repository) didn’t send an update for protobuf, which would have fixed this problem earlier.<sup><a href="#2021-08-16-python-dependency-gotchas-always-go-to-the-source-footnote-1-definition" name="2021-08-16-python-dependency-gotchas-always-go-to-the-source-footnote-1-return">1</a></sup> It seems like it’s not completely reliable for python packages, for whatever reason: I have also noticed this problem with <a href="https://github.com/mozilla/mozregression">mozregression</a>.</p>
<p>I <em>suspect</em> (though can’t confirm) that the problem here is a backwards-incompatible change made to either <code>protobuf</code> or one of the packages that uses it. However, the nature of the incompatibility seems subtle: bigquery-etl works fine with the old set of dependencies we run in continuous integration and it appears to only come up in specific circumstances (i.e. mine). Unfortunately, I need to get back to what I was <em>actually</em> planning to work on and don’t have time to unwind the rather set of complex interactions going on here. Maybe later!</p>
<h2 id="what-i-would-have-done-differently">What I would have done differently</h2>
<p>This kind of illustrates (again) to me that while some shortcuts and heuristics can save a bunch of time and mental effort (Googling things all the time is basically standard practice in the industry at this point), sometimes you really just need to start a little closer at the problem to find a solution. I was hesitant to do this in this case because I’m never sure where those kinds of rabbit holes are going to take me (e.g. I <a href="https://github.com/mozilla/telemetry-airflow/issues/844">spent several days</a> debugging a bad interaction between Kubernetes and our airflow cluster in late 2019 with not much to show for the effort), but often all it takes is understanding the general shape of the problem to move you to a quick solution.</p>
<h2 id="other-lessons">Other lessons</h2>
<p>Here’s a couple of other things this experience reinforced for me (these are more subjective, take them or leave them):</p>
<ul>
<li>Local development environments are kind of a waste of time. The above work took me several hours and it’s going to result in ~zero user-visible improvements for anyone outside of Mozilla Data Engineering. I’m excited about the potential productivity improvements that might come from using tools like <a href="https://github.com/features/codespaces">GitHub Codespaces</a>.</li>
<li>While I can’t confirm this was the source of the problem in this particular case, in general backwards compatibility <em>on every level</em> is super important when your software has broad reach and doubly so if it’s a widely-used dependency of other software (and is thus hard to reason about in isolation). In these cases, what seems like a trivial change (e.g. improving the type signatures inside a Python library) can squander many hours of people’s time if you’re not careful. Backwards-incompatible changes, however innocuous they may seem, should always invoke <a href="https://semver.org/">a major version bump</a>.</li>
<li>Likewise, bugs in software that have broad usage (like dependabot) can have big downstream impacts. If dependabot’s version bumping for python was more reliable, we likely wouldn’t have had this problem. The glass-half-full interpretation of this is that fixing these types of issues would have an outsized benefit for the commons.</li></ul>
<div class="footnotes">
<ol>
<li id="2021-08-16-python-dependency-gotchas-always-go-to-the-source-footnote-1-definition" class="footnote-definition">
<p>As an aside, the main reason we use dependabot and aggressively update packages like <code>google-api-core</code> is due to a <a href="https://github.com/pypa/pip/issues/9644">bug in pip</a>. <a href="#2021-08-16-python-dependency-gotchas-always-go-to-the-source-footnote-1-return">↩</a></p></li></ol></div>Lightweight dashboards and reports with Irydium and surge.shurn:https-wrla-ch:-blog-2021-08-lightweight-dashboards-and-reports-with-irydium-and-surge-sh2021-08-03T15:37:35Z2021-08-03T15:37:35ZWilliam Lachance
<p>One of my main goals with <a href="https://irydium.dev">Irydium</a> is to allow it to be a part of as many data science and engineering workflows as possible (including ones I haven’t thought of). Yes, like <a href="https://alpha.iodide.io">Iodide</a> and other products, I am (slowly) building a web-based interface for building and sharing dashboards, reports, and similar things. However, I also want to fully support local and command-line based workflows. Beyond the obvious utility of being able to use your favorite text-editor to create documents, this also opens up the possibility of combining Irydium with other tools and workflows. For a slightly longer exposition on why this is desirable, I would highly recommend reading Ryan Harter’s post on the subject: <a href="https://blog.harterrt.com/coding_in_textboxes.html">Don’t make me code in your text box</a>.</p>
<h2 id="using-the-irydium-template">Using the irydium template</h2>
<p>To make getting started easier, I just created an <a href="https://github.com/irydium/irydium-template">irydium-template</a>: a simple GitHub repository which contains a minimal markdown document (a <a href="https://www.economist.com/big-mac-index">big mac index</a> visualization) which you can use as a base, as well as a bit of npm scaffolding to get you up and running quickly. To check it out via the console, I recommend using <a href="https://github.com/Rich-Harris/degit">degit</a> (the tool of choice for such things in the Svelte community):</p>
<div class="brush: bash">
<div class="colorful">
<pre><span></span>npx degit git@github.com:irydium/irydium-template.git my-notebook
npm install
npm run dev
</pre></div>
</div>
<p>This will create a webserver which renders the document (index.md) at port 3000, along with some debugging options. As you edit and save the document, the site should update automatically.</p>
<h2 id="publishing-your-work">Publishing your work</h2>
<p>When you’re happy with the results, you can create a static version of the site (an <code>index.html</code> file) by running <code>npm run build</code>. You can publish this via whatever you like: GitHub pages, Netlify / Vercel or… my new favorite service, <a href="https://surge.sh">surge.sh</a>. Surge provides a really simple hosting service for hosting static sites and works great with Irydium. Installing <em>and</em> running it locally is two commands:</p>
<div class="brush: bash">
<div class="colorful">
<pre><span></span>npm install -g surge
surge
</pre></div>
</div>
<p>Surge will prompt you for an email and a password, then will automatically publish your site at a unique URL. As an example, I published a site for the above template: <a href="https://few-blade.surge.sh">few-blade.surge.sh</a></p>
<p>Interested in chatting more about this? Feel free to reach out on the <a href="https://gitter.im/irydium/community">Irydium Gitter chat</a>.</p>Irydium @ Recurse Updatesurn:https-wrla-ch:-blog-2021-07-irydium-recurse-updates2021-07-28T19:16:42Z2021-07-28T19:16:42ZWilliam Lachance
<p>Some quick updates on where <a href="https://irydium.dev">Irydium</a> is at, roughly a week-and-a-half before my mini-sabbatical at the <a href="https://recurse.com">Recurse Centre</a> ends.</p>
<h2 id="jupyterbook-and-myst">JupyterBook and MyST</h2>
<p>I’d been admiring <a href="https://jupyterbook.org">JupyterBook</a> from afar for some time: their project philosophy appealed to me greatly. In particular, the <a href="https://myst-parser.readthedocs.io/">MyST extensions</a> to markdown seemed like a natural fit for this project and a natural point of collaboration and cross-pollination. A couple of weeks ago, I finally got in touch with some people working on that project, which prompted a few small efforts:</p>
<ul>
<li><a href="https://github.com/executablebooks/myst-vs-code/pull/32">Adding Svelte support to VSCode’s MyST Plugin</a>, which in turn prompted me to figure out <a href="https://github.com/sveltejs/language-tools/issues/1094">why the VSCode plugin for Svelte doesn’t render inline content correctly</a> (tl;dr: probably a bug in VSCode?)</li>
<li><a href="https://irydium.dev/examples#myst-directives">Adding support for a couple of MyST’s built-in directives</a> (“warning” and “note”).</li></ul>
<p><a href="https://irydium.dev/examples#myst-directives"><img src="https://i.imgur.com/A24e302.png" alt="" /></a></p>
<p>I’ve become convinced that building on top of MyST is right for both Irydium and the larger community. Increasing Irydium’s support for MyST is tracked in <a href="https://github.com/irydium/irydium/issues/123">irydium/irydium#123</a>.</p>
<h2 id="using-irydium-to-build-irydium">Using Irydium to build Irydium</h2>
<p>I’ve been spending a fair bit of time thinking of how to ma ke it easier for people to build Irydium documents through <em>composition</em> of existing documents. Landed the first pieces of this. The first is the ability to “import” a code chunk from another irydium document. There’s a few examples of this in the new <a href="https://irydium.dev/components">components section</a> of irydium.dev:</p>
<div class="figure"><img src="https://i.imgur.com/y4qNTj6.png" alt="" />
<p class="caption"></p></div>
<p>In a sense this allows you to define a reusable piece of code along with both documentation and usage examples. I think this concept will be particularly useful for supporting language plugins (which I will write about in an upcoming post).</p>
<h2 id="its-a-real-project-now">It’s a real project now</h2>
<p>I spent a bit of time last week doing some community gardening. I still consider Irydium an “experiment” but I’d like to at least open up the possibility of it being something larger. To help make that happen, I started working on some basic project governance pieces, namely:</p>
<ul>
<li>We have a <a href="https://github.com/irydium/irydium/blob/main/CODE_OF_CONDUCT.md">code of conduct</a> and <a href="https://github.com/irydium/irydium/blob/main/CONTRIBUTING.md">contributing guidelines</a>. I opted to go for the Contributor Covenant, which seems to be a good minimal viable social contract. I considered something proposing something more comprehensive (like the <a href="https://www.rust-lang.org/policies/code-of-conduct">Rust Code of Conduct</a>), but I felt that’s something for a <em>group</em> of people to discuss and debate, should the time come where Irydium is more than a one-person show. For now, I’ll do my best to make sure that everyone in Irydium’s orbit has a good experience.</li>
<li>There’s a proper issues list, including some “good first bugs” for people to look at (shout out to <a href="https://github.com/m-clare/">@m-clare</a> for submitting the first PR to Irydium!)</li>
<li>We have a <a href="https://gitter.im/irydium/community">channel on gitter</a>, also accessible <a href="https://matrix.to/#/#irydium_community:gitter.im">via Matrix</a>. Come say hi!</li></ul>
<h2 id="next-steps">Next steps</h2>
<p>There’s not a ton of time left at RC, so some of these things may have to be done in my spare time after the batch ends. That said, here’s my near-term roadmap:</p>
<ul>
<li>Add support for code chunks to output content directly to the DOM (currently the only way to output to an Irydium document is through a Svelte component). This will be particularly important for Python support, where people expect the output of a cell running <a href="https://github.com/altair-viz">altair</a> or <a href="https://github.com/matplotlib/matplotlib/">matplotlib</a> to display directly in the document (as they do in Jupyter). Tracked in <a href="https://github.com/irydium/irydium/issues/122">irydium/irydium#122</a>.</li>
<li>Integrate <a href="https://ellx.io/">ellx.io</a>’s next-generation JavaScript bundler, <a href="https://github.com/dmaevsky/tokamak">tokamak</a>. This should make building irydium documents much more robust and error proof and paves the way to further improvements. Special shout-out to the ellx developers for being so friendly and open to collaboration: ellx is a novel approach to application development and definitely worth checking out if you haven’t already. Tracked in <a href="https://github.com/irydium/irydium/issues/125">irydium/irydium#125</a>.</li>
<li>Finish and document support for language plugins (and make another blog post especially about them, they’re cool!). Tracked in <a href="https://github.com/irydium/irydium/issues/144">irydium/irydium#144</a>.</li></ul>10 years at Mozillaurn:https-wrla-ch:-blog-2021-07-10-years-at-mozilla2021-07-12T16:30:42Z2021-07-12T16:30:42ZWilliam Lachance
<p>Yesterday (July 11, 2021) was the 10 year anniversary of starting at the Mozilla Corporation. My life has changed a <em>ton</em> in those years: in that time I ended a marriage, changed the city in which I live two times, and took up religion<sup><a href="#2021-07-12-10-years-at-mozilla-footnote-1-definition" name="2021-07-12-10-years-at-mozilla-footnote-1-return">1</a></sup>. Mozilla has also changed pretty drastically in my time here, <a href="https://blog.mozilla.org/blog/2020/08/11/changing-world-changing-mozilla/">especially in the last year</a>.</p>
<p>Yet somehow I’m still at it, for more or less for the same reasons that led me to accept my initial offer to join the <a href="https://wiki.mozilla.org/EngineeringProductivity">A-team</a>.<sup><a href="#2021-07-12-10-years-at-mozilla-footnote-2-definition" name="2021-07-12-10-years-at-mozilla-footnote-2-return">2</a></sup> The Internet has the immense potential to be a force for individual empowerment and yet more than ever, we see this technology used to consolidate unchecked power, spread misinformation, and generally exploit people. Mozilla is not perfect (no organization is: 10 years anywhere will teach you that), but it’s one of the few remaining counter-forces to these accelerating trends. While I’m currently taking a bit of a break to <a href="https://wrla.ch/blog/2021/06/mini-sabbatical-and-introducing-irydium/">explore some stuff on my own</a>, I am looking forward to getting back to work on <a href="https://www.mozilla.org/en-CA/about/manifesto/">the mission</a> when I return in mid-August.</p>
<div class="footnotes">
<ol>
<li id="2021-07-12-10-years-at-mozilla-footnote-1-definition" class="footnote-definition">
<p>To the extent that Zen Buddhism is a religion. <a href="#2021-07-12-10-years-at-mozilla-footnote-1-return">↩</a></p></li>
<li id="2021-07-12-10-years-at-mozilla-footnote-2-definition" class="footnote-definition">
<p>I’ve since moved to <a href="https://wiki.mozilla.org/Data">Data @ Mozilla</a> <a href="#2021-07-12-10-years-at-mozilla-footnote-2-return">↩</a></p></li></ol></div>Adding persistence to Irydium with Supabaseurn:https-wrla-ch:-blog-2021-07-adding-persistence-to-irydium-with-supabase2021-07-05T15:09:56Z2021-07-05T15:09:56ZWilliam Lachance
<p>Entering the second week of <a href="https://recurse.com">Recurse</a>. Besides orientation and a few adventures in pair programming (special shout out to <a href="http://universalities.com/">Jane Adams</a> for trying out Irydium with me!), I spent most of my time attempting to get document saving & loading working with Irydium.</p>
<p>I learned from <a href="https://alpha.iodide.io">Iodide</a> that not having a good document sharing story really inhibits collaboration and sharing, which is something I explicitly want to do here at the Recurse centre (and in general for this project). That said, this isn’t actually an area I want to spend a lot of time on right now: it’s the shape of problem I’ve solved many times before (and that has been solved by many others). I’d rather spend my time over the next few weeks on things I haven’t had much of a chance to look at or pursue in my day-to-day.</p>
<p>So, to try to keep the complexity down, I decided to take the same approach as the <a href="https://svelte.dev/repl">svelte repl</a>, which aims only to allow the reproduction of simple examples. It allows you to save anything you type in it and also browse anything that you had previously saved. That’s not going to replace GitHub, but it’s more than enough to get started.</p>
<h2 id="supabase">Supabase</h2>
<p>So with that goal in mind, how to do go about it? If I wanted to completely fall back on my previous knowledge, I could have gone for the tried + true approach of Django / Heroku to add a persistence layer (what I did for Iodide). That would have had the benefit of being familiar but would also have increased the overall implementation complexity of Irydium considerably. In the past year, I’ve become convinced that <a href="https://en.wikipedia.org/wiki/Serverless_computing">serverless</a> approaches to building web applications are the wave of the future, at least for applications like this one. They’re easier to set up, easier to develop, and (generally speaking) cheaper to deploy. Just before I launched, I set up <a href="https://irydium.dev">irydium.dev</a> as a static site on <a href="https://netlify.com">Netlify</a> and it’s been a great experience: deploys are super fast and it’s easy to reason about what’s going on “under the hood” (since there’s not a much of a hood to look under).</p>
<p>With that in mind, I decided to take a (small) gamble and give <a href="https://supabase.io/">Supabase</a> a try for this one after determining it would be compatible with the approach I wanted to take. Supabase bills itself as a “Firebase Alternative” (<a href="https://firebase.google.com/">Firebase</a> is another popular solution for bootstrapping simple web applications with persistence). In contrast to Firebase, Supabase uses a standard database technologies (Postgres!) and has a nice JavaScript SDK and a bunch of well-written tutorials (including <a href="https://supabase.io/docs/guides/with-svelte">one especially for Svelte</a>).</p>
<p>The naive model for integrating with Supabase is pretty simple:</p>
<ul>
<li>Set up a Supabase application, which provides you with a unique API endpoint to make web requests (this endpoint can be exposed publicly).</li>
<li>Have your client authenticate with an OAuth provider (e.g. GitHub, GitLab), then store an authentication token in localStorage.</li>
<li>You can then make requests to the above endpoint with the authentication token, which lets Supabase use row-level security to restrict modifications to the database: in this case, we can restrict users to updating their own documents.</li></ul>
<p>I’d say it probably took me 20–30 hours to get the feature working end-to-end (including documentation), which wasn’t too bad. My impressions were pretty positive: the aforementioned tutorial is pretty decent, the supabase-js library provides a nice ORM-like abstraction over SQL and integrates nicely with Svelte. In general working with Supabase felt pretty familiar to me from previous experiences writing database-backed applications, which I take as a very good sign.</p>
<p>The part that felt the weirdest was writing raw SQL to set up the “documents” table that Irydium uses: SQL is something I’m fairly used to writing because of my experiences at Mozilla, but I imagine this might be off-putting to someone newer to writing these types of things. Also, I have some concerns of how maintainable a Supabase database is over the long term: while it was easy enough to <a href="https://github.com/irydium/irydium/blob/f816ea6444c94635972a57bc92d7770398117c1e/README.md#working-on-the-site">document the currently-simple setup instructions in the README</a>, I do somewhat fear the prospect of managing my database via their SQL console. Something like Django’s <a href="https://docs.djangoproject.com/en/3.2/topics/migrations/">schema migrations</a> and <a href="https://docs.djangoproject.com/en/3.2/howto/custom-management-commands/">management commands</a> would be a welcome addition to Supabase’s SDK.</p>
<h2 id="netlify-functions">Netlify functions</h2>
<p>The above approach isn’t what most people would consider to be “best practice”<sup><a href="#2021-07-05-adding-persistence-to-irydium-with-supabase-footnote-1-definition" name="2021-07-05-adding-persistence-to-irydium-with-supabase-footnote-1-return">1</a></sup>. In particular, storing credentials in localStorage is probably not the best idea for an application presenting interactive content like Irydium: it wouldn’t be particularly difficult for a malicious document to steal someone’s secret and send it somewhere it shouldn’t be.</p>
<p>I’m not <em>so</em> worried about it at this stage of the project, but one intriguing possibility here (that’s compatible with our current deploy set up) would be to write some simple <a href="https://www.netlify.com/products/functions/">Netlify Functions</a> to do the actual interaction with Supabase, while delegating to Netlify for the authentication itself (using <a href="https://docs.netlify.com/visitor-access/identity/">Netlify Identity</a>).</p>
<p>I experimented writing a simple function to prove out this approach and it seems to work quite well (<a href="https://github.com/irydium/irydium/blob/fecea66a1cd0bedaaab4a3e6502413c55d34ec11/packages/site/netlify_functions/post.js">source</a>, <a href="https://irydium.dev/.netlify/functions/post?id=65107940-dd88-11eb-866c-0a4e9a1089db">example</a>). This particular function is making an anonymous query to the database, but I see no obstacle to handling authenticated ones as well. Having an API under a <code>.netlify</code> namespace seems kinda weird on first blush, but I can probably get used to it.</p>
<p>I want to move on to other things now (parsers! document state visualizations!) but might poke at this more later. In the mean time, if you write/build something cool at <a href="https://irydium.dev/repl">irydium.dev/repl</a>, let me know!</p>
<div class="footnotes">
<ol>
<li id="2021-07-05-adding-persistence-to-irydium-with-supabase-footnote-1-definition" class="footnote-definition">
<p>See, for example, <a href="https://dev.to/rdegges/please-stop-using-local-storage-1i04">Please Stop Using Local Storage</a> <a href="#2021-07-05-adding-persistence-to-irydium-with-supabase-footnote-1-return">↩</a></p></li></ol></div>Irydium: Points of departureurn:https-wrla-ch:-blog-2021-06-irydium-points-of-departure2021-06-28T16:28:40Z2021-06-28T16:28:40ZWilliam Lachance
<p>So it’s my first day at the Recurse centre, which I <a href="/blog/2021/06/mini-sabbatical-and-introducing-irydium/">blogged briefly about last week</a>. I thought I’d start out by going into a bit more detail about what I’m trying to do with <a href="https://github.com/irydium/irydium">Irydium</a>. This post might be a bit discursive and some of my thoughts are only half-formed: my intent here is towards trying to <em>express some of these ideas at all</em> rather than to come up with the perfect formulation for them, which is going to take time. It is based partly on a presentation I gave at Mozilla last Friday (just before going on my 6-week leave, which starts today).</p>
<h2 id="first-principles">First principles</h2>
<p>The premise of Irydium is that despite obvious advances in terms of the ability of computers to crunch numbers and analyze data, our ability to share whatever we learn from these understandings is still far too difficult, especially for people new to the field. Even for domain experts (those with the job title “Data Engineer” or “Data Scientist” or similar) this is still more difficult than one would like.</p>
<p>I’ve made a few observations over the past couple years of trying to explain and document Mozilla’s data platform that I think form a good starting point for trying to close the gap:</p>
<ul>
<li><em>Text is pretty great</em>. Writing, just plain text, is (in my opinion) the single best medium for giving context to data. In terms of raw information density and ability to communicate complex ideas, nothing beats it. If you haven’t read it before, the essay <a href="https://graydon2.dreamwidth.org/193447.html">always bet on text</a> (by Graydon Hoare, creator of Rust) is well worth reading.</li>
<li><em>Markdown is pretty great too</em>. Essentially an easy-to-write superset of HTML, it’s become the medium of choice for many desktop publishing workflows and has become the basis for many efforts in the “interactive presentation” space that I’m most interested in.</li>
<li><em>Reactive Systems make Data Exposition Exposition Easier</em>. A reactive abstraction in front of your computational model reduces development times, makes your work more reproducible and is often easier for less-experienced people to understand. I’d cite the long-standing success of Excel and the recent interest in projects like Observable as evidence for this.</li></ul>
<h2 id="ok-so-what-is-irydium">Ok, so what is Irydium?</h2>
<p>Irydium is, at heart, a way to translate markdown documents into an interactive, compelling visual presentation.</p>
<div class="figure"><img src="/files/2021/06/irydium-2.png" alt="" />
<p class="caption"></p></div>
<p>My view is that publishing markdown text on the web is very close to a solved problem, and that we should build on that success rather than invent something new. This is not necessarily a new point of view (e.g. <a href="https://rmarkdown.rstudio.com/">Rmarkdown</a> and <a href="https://jupyterbook.org/">JupyterBook</a> have similar premises) but I think some aspects of Irydium’s approach are mildly novel (or at least within the space of “not generally accepted ideas”).</p>
<p>If you want to get a bit of a flavor for how it works, visit the demonstration site (<a href="https://irydium.dev">irydium.dev</a>) and play with some of the examples.</p>
<h2 id="what-makes-irydium-different-from-x">What makes Irydium different from <X>?</h2>
<p>While there are a bunch of related projects in this space, there’s a few design principles about Irydium that make it a little different from most of what’s already out there<sup><a href="#2021-06-28-irydium-points-of-departure-footnote-1-definition" name="2021-06-28-irydium-points-of-departure-footnote-1-return">1</a></sup>:</p>
<ul>
<li><em>Reactive</em>: Irydium is reactive in the same way that a spreadsheet is — that is, any individual change you make will immediately flow to the rest of the system. This provides a more intuitive model for the creator of the document and also makes it easier to create truly interactive visualizations.</li>
<li><em>Idempotent</em>: in Irydium, a source document will yield the same presentation every time it’s run. There’s no need to reason about what the state of the “kernel” is. This is a highly valuable property when thinking about how to make your analyses reproducible.</li>
<li><em>Familiar</em>: Irydium uses as few <em>novel</em> concepts and technologies as possible: it builds on some of the best ideas and technologies produced by the open source community: <a href="https://python.org">Python</a>, <a href="https://pyodide.org">pyodide</a>, <a href="https://svelte.dev">Svelte</a>, <a href="https://mdsvex.com">mdsvex</a>, <a href="https://myst-parser.readthedocs.io/en/latest/">MyST</a> and a few others — chosen for having a reasonably shallow learning curve.</li>
<li><em>Hackable</em>: While I’m working on an online environment to build and share irydium documents, it’s also fully possible to do so using the tools you know and love like Visual Studio Code.</li></ul>
<h2 id="related-projects">Related projects</h2>
<p>With the above caveats, there are still a number of projects that overlap with Irydium’s ideas and/or design goals. A few that seem worth mentioning here:</p>
<ul>
<li><a href="https://alpha.iodide.io">Iodide</a>: This is the obvious one, at least for those who have been following my work for a while. Iodide was an experiment in making a “web native” version of a scientific notebook: it uses the cell-based computational model that will be familiar to anyone who’s used Jupyter, but all the computation happens on the client. It is probably most famous for launching <a href="https://pyodide.org">pyodide</a>, a port of Python to WebAssembly (that Irydium now uses to support Python). I feel like it has a number of design issues (some of which I’ve <a href="/blog/2020/11/iodide-retrospective/">blogged about previously</a>) and is not currently in active development.</li>
<li><a href="https://observablehq.com">Observable</a>: Client-side reactive notebooks, commercial backing, broadly used in the D3 community. Shares Irydium’s reactive approach, departs from it in terms of using a custom file format and emphasizing their interactive editing and collaboration environment (which is indeed quite impressive). I’ve used Observable for a few small work things (<a href="https://observablehq.com/@wlach/mozregression-public-usage-dashboard">example</a>) and while there’s a lot I like about it, I am a bit non-plussed by how many wheels it reinvents and the implicit lock-in to a single vendor.<sup><a href="#2021-06-28-irydium-points-of-departure-footnote-2-definition" name="2021-06-28-irydium-points-of-departure-footnote-2-return">2</a></sup></li>
<li><a href="https://starboard.gg">Starboard</a>: Similar in some ways to Iodide, but in active development. I’ve started chatting a bit with the core developers on whether there might be areas we could collaborate.</li>
<li><a href="https://ellx.io/">Ellx</a>: I found out a bit about this relatively recently, via the Svelte discord. Actually very close in some ways to Irydium in terms of choices of technology (e.g. <a href="https://svelte.dev">Svelte</a>). Again, in initial chats with the core developers on possible collaborations.</li></ul>
<h2 id="success-criteria">Success criteria</h2>
<p>My intent with Irydium, at this point in its development, is to prove out some concepts and see where they lead. While I’d welcome it if Irydium became a successful, widely adopted environment for building interactive data visualizations, I’d also be totally happy with other outcomes, such as:</p>
<ol>
<li>Providing a source of ideas and/or code for other people.</li>
<li>Working on (or with) Irydium being a good learning experience both for myself and others</li></ol>
<hr />
<div class="footnotes">
<ol>
<li id="2021-06-28-irydium-points-of-departure-footnote-1-definition" class="footnote-definition">
<p>Please don’t conflate “unique” with “superior”: I’m well aware that all designs come with trade offs. In particular, Irydium’s approach will almost certainly make it difficult / impossible to directly interact with “big data” systems in an efficient way. <a href="#2021-06-28-irydium-points-of-departure-footnote-1-return">↩</a></p></li>
<li id="2021-06-28-irydium-points-of-departure-footnote-2-definition" class="footnote-definition">
<p>There is at least one effort (<a href="https://github.com/asg017/dataflow">Dataflow</a>) to allow editing Observable documents without using Observable itself, which is interesting. <a href="#2021-06-28-irydium-points-of-departure-footnote-2-return">↩</a></p></li></ol></div>Mini-sabbatical and introducing Irydiumurn:https-wrla-ch:-blog-2021-06-mini-sabbatical-and-introducing-irydium2021-06-23T21:15:15Z2021-06-23T21:15:15ZWilliam Lachance
<p>Approaching my 10-year moz-iversary in July, I’ve decided it’s time to take a bit of a mini-sabbatical: I’ll be out (and trying as hard as possible not to check bugmail) from Friday, June 25th until August 9th. During this time, I’ll be doing a batch at the <a href="https://recurse.com">Recurse Centre</a> (something like a writer’s retreat for programmers), exploring some of my interests around data visualization and analysis that don’t quite fit into my role as a Data Engineer here at Mozilla.</p>
<p>In particular, I’m planning to work a bunch on a project tentatively called “Irydium”, which pursues some of the ideas I <a href="https://wrla.ch/blog/2020/11/iodide-retrospective/">sketched out last year in my Iodide retrospective</a> and a few more besides. I’ve been steadily working on it in my off hours, but it’s become clear that some of the things I want to pursue would benefit from more dedicated attention and the broader perspective that I’m hoping the Recurse community will be able to provide.</p>
<div class="figure"><img src="/files/2021/06/irydium.png" alt="" />
<p class="caption"></p></div>
<p>I had meant to write up a proper blog post to announce the project before I left, but it looks like I’m pretty much out of time. Instead, I’ll just offer up the examples on the newly-minted <a href="https://irydium.dev">irydium.dev</a> and invite people to contact me if any of the ideas on the site sounds interesting. I’m hoping to blog a whole bunch while I’m there, but probably not under the Mozilla tag. Feel free to add wrla.ch to your RSS feed if you want to follow what I’m up to!</p>Glean Dictionary updatesurn:https-wrla-ch:-blog-2021-06-glean-dictionary-updates2021-06-02T16:01:52Z2021-06-02T16:01:52ZWilliam Lachance
<p>(<a href="https://blog.mozilla.org/data/2021/06/02/this-week-in-glean-glean-dictionary-updates/">this is a cross-post from the data blog</a>)</p>
<p>Lots of progress on the Glean Dictionary since I made the initial release announcement a couple of months ago. For those coming in late, the Glean Dictionary is intended to be a <a href="https://en.wikipedia.org/wiki/Data_dictionary">data dictionary</a> for applications built using the <a href="https://mozilla.github.io/glean">Glean SDK</a> and <a href="https://github.com/mozilla/glean.js/">Glean.js</a>. This currently includes Firefox for Android and Firefox iOS, as well as newer initiatives like <a href="https://rally.mozilla.org">Rally</a>. Desktop Firefox <em>will</em> use Glean in the future, see <a href="https://firefox-source-docs.mozilla.org/toolkit/components/glean/index.html">Firefox on Glean (FoG)</a>.</p>
<h2 id="production-url">Production URL</h2>
<p>We’re in production! You can now access the Glean Dictionary at <a href="https://dictionary.telemetry.mozilla.org">dictionary.telemetry.mozilla.org</a>. The old protosaur-based URL will redirect.</p>
<h2 id="glean-dictionary--looker--">Glean Dictionary + Looker = ❤️</h2>
<p>At the end of last year, Mozilla chose <a href="https://looker.com">Looker</a> as our internal business intelligence tool. Frank Bertsch, Daniel Thorn, Anthony Miyaguchi and others have been building out first class support for Glean applications inside this platform, and we’re starting to see these efforts bear fruit. Looker’s explores are far easier to use for basic data questions, opening up data based inquiry to a much larger cross section of Mozilla.</p>
<p>I recorded a quick example of this integration here:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/B635wgZy7Iw" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="allowfullscreen"></iframe>
<p>Note that Looker access is restricted to Mozilla employees and NDA’d volunteers. Stay tuned for <a href="https://docs.telemetry.mozilla.org/cookbooks/public_data.html">more public data</a> to be indexed inside the Glean Dictionary in the future.</p>
<h2 id="glean-annotations">Glean annotations!</h2>
<p>I did up the first cut of a GitHub-based system for adding annotations to metrics — acting as a knowledge base for things data scientists and others have discovered about Glean Telemetry in the field. This can be <em>invaluable</em> when doing new analysis. A good example of this is the annotation added for the <a href="https://dictionary.telemetry.mozilla.org/apps/firefox_ios/metrics/app_opened_as_default_browser">opened as default browser</a> metric for Firefox for iOS, which has several gotchas:</p>
<div class="figure"><img src="/files/2021/06/annotations-example.png" alt="" />
<p class="caption"></p></div>
<p>Many thanks to Krupa Raj and Leif Oines for producing the requirements which led up to this implementation, as well as their evangelism of this work more generally inside Mozilla. Last month, Leif and I did a presentation about this at Data Club, which has been syndicated onto YouTube:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/aGjrXhXNRq8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="allowfullscreen"></iframe>
<p>Since then, we’ve had a very successful working session with some people Data Science and have started to fill out an initial set of annotations. You can see the progress in the <a href="https://github.com/mozilla/glean-annotations">glean-annotations</a> repository.</p>
<h2 id="other-improvements">Other Improvements</h2>
<p>Lots more miscellaneous improvements and fixes have gone into the Glean Dictionary in the last several months: see our <a href="https://github.com/mozilla/glean-dictionary/releases">releases</a> for a full list. One thing that irrationally pleases me are the <a href="https://github.com/mozilla/glean-dictionary/pull/626">new labels Linh Nguyen added last week</a>: colorful and lively, they make it easy to see when a Glean Metric is coming from a library:</p>
<div class="figure"><img src="/files/2021/06/labels-example.png" alt="" />
<p class="caption"></p></div>
<h2 id="future-work">Future work</h2>
<p>The Glean Dictionary is just getting started! In the next couple of weeks, we’re hoping to:</p>
<ul>
<li>Expand the Looker integration outlined above, as our deploy takes more shape.</li>
<li>Work on adding “feature” classification to the Glean Dictionary, to make it easier for product managers and other non-engineering types to quickly find the metrics and other information they need without needing to fully understand what’s in the source tree.</li>
<li>Continue to refine the user interface of the Glean Dictionary as we get more feedback from people using it across Mozilla.</li></ul>
<p>If you’re interested in getting involved, join us! The Glean Dictionary is developed in the open using cutting edge front-end technologies like <a href="https://svelte.dev">Svelte</a>. Our conviction is that being transparent about the data Mozilla collects helps us build trust with our users and the community. We’re a friendly group and hang out on the <a href="https://chat.mozilla.org/#/room/#glean-dictionary:mozilla.org">#glean-dictionary channel</a> on Matrix.</p>mozregression update May 2021urn:https-wrla-ch:-blog-2021-05-mozregression-update-may-20212021-05-10T13:56:43Z2021-05-10T13:56:43ZWilliam Lachance
<p>Just wanted to give some quick updates on the state of <a href="https://mozilla.github.io/mozregression">mozregression</a>.</p>
<h2 id="anti-virus-false-positives">Anti-virus false positives</h2>
<p>One of the persistent issues with mozregression is that it seems to be <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1647533">persistently detected as a virus by many popular anti-virus scanners</a>. The causes for this are somewhat complex, but at root the problem is that mozregression requires fairly broad permissions to do the things it needs to do (install and run copies of Firefox) and thus its behavior is hard to distinguish from a piece of software doing something malicious.</p>
<p>Recently there have been a number of mitigations which seem to be improving this situation:</p>
<ul>
<li>:bryce has been submitting copies of mozregression to Microsoft so that Windows Defender (probably the most popular anti-virus software on this platform) doesn’t flag it.</li>
<li>I recently <a href="https://github.com/mozilla/mozregression/releases">released mozregression 4.0.17</a>, which upgrades the GUI dependency for pyinstaller to a later version which sets PE checksums correctly on the generated executable (<a href="https://github.com/pyinstaller/pyinstaller/issues/5579">pyinstaller/pyinstaller#5579</a>).</li></ul>
<p>It’s tempting to lament the fact that this is happening, but in a way I can understand it’s hard to reliably detect what kind of software is legitimate and what isn’t. I take the responsibility for distributing this kind of software seriously, and have pretty strict limits on who has access to the mozregression GitHub repository and what pull requests I’ll merge.</p>
<h2 id="ci-ported-to-github-actions">CI ported to GitHub Actions</h2>
<p>Due to changes in Travis’s policies, we needed to migrate continuous integration for mozregression to GitHub actions. You can see the gory details in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1686039">bug 1686039</a>. One possibly interesting wrinkle to others: due to Mozilla’s security policy, we can’t use (most) external actions inside our GitHub repository. I thus rewrote the logic for uploading a mozregression release to GitHub for MacOS and Linux GUI builds (Windows builds are still happening via <a href="https://www.appveyor.com/">AppVeyor</a> for now) <a href="https://github.com/mozilla/mozregression/blob/495ef37e701709dce3a4b76ea67ec5b1f26043be/.github/workflows/build.yml#L86">from scratch</a>. Feel free to check the above out if you have a similar need.</p>
<h2 id="macos-big-sur">MacOS Big Sur</h2>
<p>As of version 4.0.17, the mozregression GUI now works on MacOS Big Sur. It is safe to ask community members to install and use it on this platform (though <a href="https://mozilla.github.io/mozregression/install.html#mozregression-gui">note the caveats</a> due to the bundle being unsigned).</p>
<h2 id="usage-dashboard">Usage Dashboard</h2>
<p>Fulfilling a promise I implied last year, I created a <a href="https://docs.telemetry.mozilla.org/cookbooks/public_data.html">public dataset</a> for mozregression and created an <a href="https://observablehq.com/@wlach/mozregression-public-usage-dashboard">dashboard tracking mozregression use</a> using <a href="https://observablehq.com/">Observable</a>. There are a few interesting insights and trends there that can be gleaned from our telemetry. I’d be curious if the community can find any more!</p>Blog moving back to wrla.churn:https-wrla-ch:-blog-2021-03-blog-moving-back-to-wrla-ch2021-03-21T07:12:19Z2021-03-21T07:12:19ZWilliam Lachance
<p>House keeping news: I’m moving this blog back to the <a href="https://wrla.ch">wrla.ch</a> domain from wlach.github.io. This domain sorta kinda worked before (I set up a <a href="https://netlify.com">netlify</a> deploy a couple years ago), but the software used to generate this blog referenced github all over the place in its output, so it didn’t really work as you’d expect. Anyway, this will be the last entry published on wlach.github.io: my plan is to turn that domain into a set of redirects in the future.</p>
<p>I don’t know how many of you are out there who still use RSS, but if you do, please update your feeds. I have filed a bug to update my Planet Mozilla entry, so hopefully the change there will be seamless.</p>
<p>Why? Recent events have made me not want to tie my public web presence to a particular company (especially a larger one, like Microsoft). I don’t have any immediate plans to move this blog off of github, but this gives me that option in the future. For those wondering, the original rationale for moving <em>to</em> github is in <a href="/blog/2016/01/new-year-new-blog/">this post</a>. Looking back, the idea of moving away from a VPS and WordPress made sense, the move away from my own domain less so. I think it may have been harder to set up static hosting (esp. with HTTPS) at that time… or I might have just been ignorant.</p>
<p>In related news, I decided to reactivate my twitter account: you can once again find me there as <a href="https://twitter.com/wrlach">@wrlach</a> (my old username got taken in my absence). I’m not totally thrilled about this (I basically stand by what I wrote a <a href="/blog/2018/01/quitting-twitter/">few years ago</a>, except maybe the concession I made to Facebook being “ok”), but Twitter seems to be where my industry peers are. As someone who doesn’t have a large organic following, I’ve come to really value forums where I can share my work. That said, I’m going to be very selective about what I engage with on that site: I appreciate your understanding.</p>Community @ Mozilla: People First, Open Source Secondurn:https-wrla-ch:-blog-2021-02-community-mozilla-people-first-open-source-second2021-02-24T14:08:16Z2021-02-24T14:08:16ZWilliam Lachance
<p>It’s coming up on ten years at Mozilla for me, by far the longest I’ve held any job personally and exceedingly long by the standards of the technology industry. When I joined up in Summer 2011 to work on <a href="https://wiki.mozilla.org/EngineeringProductivity">Engineering Productivity</a><sup><a href="#2021-02-24-community-mozilla-people-first-open-source-second-footnote-1-definition" name="2021-02-24-community-mozilla-people-first-open-source-second-footnote-1-return">1</a></sup>, I really did see it as a dream job: I’d be paid to work full time on free software, which (along with open data and governance) I genuinely saw as one of the best hopes for the future. I was somewhat less sure about Mozilla’s “mission”: the notion of protecting the “open web” felt nebulous and ill-defined and the <a href="https://www.mozilla.org/en-CA/about/manifesto/">Mozilla Manifesto</a> seemed vague when it departed from the practical aspects of shipping a useful open source product to users.</p>
<p>It seems ridiculously naive in retrospect, but I can remember thinking at the time that the right amount of “open source” would solve all the problems. What can I say? It was the era of the <a href="https://en.wikipedia.org/wiki/Arab_Spring">Arab Spring</a>, WikiLeaks had not yet become a scandal, Google still felt like something of a benevolent upstart, even Facebook’s mission of “making the world more connected” sounded great to me at the time. If we could just push more things out in the open, then the right solutions would become apparent and fixing the structural problems society was facing would become easy!</p>
<p>What a difference a decade makes. The events of the last few years have demonstrated (conclusively, in my view) that open systems aren’t necessarily a protector against abuse by governments, technology monopolies and ill-intentioned groups of individuals alike. Amazon, Google and Facebook are (still) some of the top contributors to key pieces of open source infrastructure but it’s now beyond any doubt that they’re <em>also</em> responsible for amplifying a very large share of the problems global society is experiencing.</p>
<p>At the same time, some of the darker sides of open source software development have become harder and harder to ignore. In particular:</p>
<ul>
<li>Harassment and micro aggressions inside open source communities is rampant: aggressive behaviour in issue trackers, personal attacks on discussion forums, the list goes on. Women and non-binary people are disproportionately affected, although this behaviour exacts a psychological toll on everyone.</li>
<li>Open source software as exploitation: I’ve worked with <em>lots</em> of contributors while at Mozilla. It’s hard to estimate this accurately, but based on some back-of-the-envelope calculations, I’d estimate that the efforts of community volunteers on projects I’ve been involved in have added up to (conservatively) to hundreds of thousands of U.S. dollars in labour which has never been directly compensated monetarily. Based on this experience (as well as what I’ve observed elsewhere), I’d argue that Mozilla as a whole could not actually <em>survive</em> on a sustained basis without unpaid work, which (at least on its face) seems highly problematic and creates a lingering feeling of guilt given how much I’ve benefited financially from my time here.</li>
<li>It’s a road to burnout. Properly managing and nurturing an open source community is deeply complex work, involving a sustained amount of both attention and <a href="https://en.wikipedia.org/wiki/Emotional_labor">emotional labour</a> — this is difficult <a href="https://noidea.dog/glue">glue work</a> that is not always recognized or supported by peers or management. Many of the people I’ve met over the years (community volunteers and Mozilla employees alike) have ended up feeling like it just isn’t worth the effort and have either stopped doing it or have outright left Mozilla. If it weren’t for an intensive meditation practice which I established around the time I started working here, I suspect I would have been in this category by now.</li></ul>
<p>All this has led to a personal crisis of faith. Do openness and transparency inherently lead to bad outcomes? Should I continue to advocate for it in my position? As I mentioned above, the opportunity to work in the open with the community is the main thing that brought me to Mozilla— if I can’t find a way of incorporating this viewpoint into my work, what am I even doing here?</p>
<p>Trying to answer these questions, I went back to the manifesto that I just skimmed over in my early days. Besides openness — what are Mozilla’s values, really, and do I identify with them? Immediately I was struck by how much it felt like it was written <em>explicitly for</em> the present moment (even aside from the <a href="https://blog.mozilla.org/blog/2018/03/29/mozilla-marks-20th-anniversary-commitment-better-human-experiences-online/">addendums</a> which were added in 2018). Many points seem to confront problems we’re grappling with now which I was only beginning to perceive ten years ago.</p>
<p>Beyond that, there was also something that resonated with me on a deeper level. There were a few points, highlighted in bold, that really stood out:</p>
<ol>
<li>The internet is an integral part of modern life—a key component in education, communication, collaboration, business, entertainment and society as a whole.</li>
<li>The internet is a global public resource that must remain open and accessible.</li>
<li><strong>The internet must enrich the lives of individual human beings.</strong></li>
<li><strong>Individuals’ security and privacy on the internet are fundamental and must not be treated as optional.</strong></li>
<li><strong>Individuals must have the ability to shape the internet and their own experiences on the internet.</strong></li>
<li>The effectiveness of the internet as a public resource depends upon interoperability (protocols, data formats, content), innovation and decentralized participation worldwide.</li>
<li>Free and open source software promotes the development of the internet as a public resource.</li>
<li>Transparent community-based processes promote participation, accountability and trust.</li>
<li><strong>Commercial involvement in the development of the internet brings many benefits; a balance between commercial profit and public benefit is critical.</strong></li>
<li><strong>Magnifying the public benefit aspects of the internet is an important goal, worthy of time, attention and commitment.</strong></li></ol>
<p>I think it’s worth digging beneath the surface of these points: what is the underlying value system behind them? I’d argue it’s this, simply put: <em>human beings really do matter</em>. They’re not just line items in a spreadsheet or some other resource to be optimized. They are an end in of themselves. <em>People</em> (more so than a software development methodology) are the reason why I show up every day to do the work that I do. This is really an absolute which has enduring weight: it’s a foundational truth of every major world religion to say nothing of modern social democracy.</p>
<p>What does working and building in then open mean then? As we’ve seen above, it certainly isn’t something I’d consider “good” all by itself. Instead, I’d suggest it’s a <em>strategy</em> which (if we’re going to follow it) should <em>come out</em> of that underlying recognition of the worth of Mozilla’s employees, community members, and users. Every single one of these people matter, deeply. I’d argue then, that Mozilla should consider the following factors in terms of how we work in the open:</p>
<ul>
<li>Are our spaces<sup><a href="#2021-02-24-community-mozilla-people-first-open-source-second-footnote-2-definition" name="2021-02-24-community-mozilla-people-first-open-source-second-footnote-2-return">2</a></sup> generally safe for people of all backgrounds to be their authentic selves? This not only means free from sexual harassment and racial discrimination, but also that they’re able to work to their full potential. This means creating opportunities for <em>everyone</em> to <a href="/blog/2018/11/making-contribution-work-for-firefox-tooling-and-data-projects/">climb the contribution curve</a>, among other things.</li>
<li>We need to be more honest and direct about the economic benefits that community members bring to Mozilla. I’m not sure exactly what this means right now (and of course Mozilla’s options are constrained both legally and economically), but we need to do better about acknowledging their contributions to Mozilla’s bottom line and making sure there is a fair exchange of value on both sides. At the <em>very minimum</em>, we need to make sure that people’s contributions help them grow professionally or otherwise if we can’t guarantee monetary compensation for their efforts.</li>
<li>We need to acknowledge the efforts that our employees make in creating functional communities. This work does not come for free and we need to start acknowledging it in both our career development paths and when looking at individual performance. Similarly, we need to provide better guidance and mentorship on how to do this work in a way that does not extract too hard a personal toll on the people involved — this is a complex topic, but a lot of it in my opinion comes down to better onboarding practices (which is something we should be doing anyway) as well as setting better boundaries (both in terms of work/life balance, as well as what you’ll accept in your interactions).</li>
<li>Finally, what is the end result of our work? Do the software and systems we build genuinely enrich people’s lives? Do they become better informed after using our software? Do they make them better decisions? Free software might be good in itself, but one must also factor in <em>how it is used</em> when measuring its social utility (see: Facebook).</li></ul>
<p>None of the above is easy to address. But the alternatives are either close everything down to public participation (which I’d argue will lead to the death of Mozilla as an organization: it just doesn’t have the resources to compete in the marketplace without the backing of the community) or continue down the present path (which I don’t think is sustainable either). The last ten years have shown that the “open source on auto-pilot” approach just doesn’t work.</p>
<p>I suspect these problems aren’t specific to Mozilla and affect other communities that work in the open. I’d be interested in hearing other perspectives on this family of problems: if you have anything to add, my contact information is below.</p>
<div class="footnotes">
<ol>
<li id="2021-02-24-community-mozilla-people-first-open-source-second-footnote-1-definition" class="footnote-definition">
<p>I’ve since moved to the <a href="https://wiki.mozilla.org/Data">Data team</a>. <a href="#2021-02-24-community-mozilla-people-first-open-source-second-footnote-1-return">↩</a></p></li>
<li id="2021-02-24-community-mozilla-people-first-open-source-second-footnote-2-definition" class="footnote-definition">
<p>This includes our internal communications channels like our <a href="https://wiki.mozilla.org/Matrix">Matrix instance</a> as well as issue trackers like Bugzilla. There’s also a question of what to do about non-Mozilla channels, like Twitter or the <a href="https://news.ycombinator.com">Orange Site</a>. Although not Mozilla spaces, these places are often vectors for harassment of community members. I don’t have any good answers for what to do about this, aside from offering my solidarity and support to those suffering abuse on these channels. Disagreement with Mozilla’s strategy or policy is one thing, but personal attacks, harassment, and character assasination is never ok— no matter where it’s happening. <a href="#2021-02-24-community-mozilla-people-first-open-source-second-footnote-2-return">↩</a></p></li></ol></div>The Glean Dictionaryurn:https-wrla-ch:-blog-2021-01-the-glean-dictionary2021-01-27T13:53:44Z2021-01-27T13:53:44ZWilliam Lachance
<p><em>(“This Week in Glean” is a series of blog posts that the Glean Team at Mozilla is using to try to communicate better about our work. They could be release notes, documentation, hopes, dreams, or whatever: so long as it is inspired by Glean. You can find <a href="https://mozilla.github.io/glean/book/appendix/twig.html">an index of all TWiG posts online.</a>)</em></p>
<p>On behalf of Mozilla’s Data group, I’m happy to announce the availability of the first milestone of the Glean Dictionary, a project to provide a comprehensive “data dictionary” of the data Mozilla collects inside its products and how it makes use of it. You can access it via this development URL:</p>
<p><a href="https://dictionary.protosaur.dev/">https://dictionary.protosaur.dev/</a></p>
<div class="figure"><img src="/files/2021/01/glean-dictionary.png" alt="" />
<p class="caption"></p></div>
<p>The goal of this first milestone was to provide an equivalent to the <a href="https://probes.telemetry.mozilla.org">popular “probe” dictionary</a> for newer applications which use the Glean SDK, such as Firefox for Android. As Firefox on Glean (FoG) comes together, this will also serve as an index of what data is available for Firefox and how to access it.</p>
<p>Part of the vision of this project is to act as a showcase for Mozilla’s practices around <a href="https://www.mozilla.org/en-US/about/policy/lean-data/">lean data</a> and <a href="https://wiki.mozilla.org/Firefox/Data_Collection">data governance</a>: you’ll note that every metric and ping in the Glean Dictionary has a data review associated with it — giving the general public a window into what we’re collecting and why.</p>
<p>In addition to displaying a browsable inventory of the low-level metrics which these applications collect, the Glean Dictionary also provides:</p>
<ul>
<li>Code search functionality (via <a href="https://searchfox.org">Searchfox</a>) to see where any given data collection is defined and used.</li>
<li>Information on how this information is represented inside Mozilla’s BigQuery data store.</li>
<li>Where available, links to browse / view this information using the <a href="https://glam.telemetry.mozilla.org">Glean Aggregated Metrics Dashboard</a> (GLAM).</li></ul>
<p>Over the next few months, we’ll be expanding the Glean Dictionary to include derived datasets and dashboards / reports built using this data, as well as allow users to add their own annotations on metric behaviour via a GitHub-based documentation system. For more information, see the <a href="https://docs.google.com/document/d/1OkTWA3rsSJ0m5g9GDnxXVUMkJP-xJMQk_bDgDq-Z9xM/edit#">project proposal</a>.</p>
<p>The Glean Dictionary is the result of the efforts of many contributors, both inside and outside Mozilla Data. Special shout-out to <a href="https://www.linh-nguyen.com/outreachy">Linh Nguyen</a>, who has been moving mountains inside the codebase as part of an Outreachy internship with us. We welcome your feedback and involvement! For more information, see our <a href="https://github.com/mozilla/glean-dictionary">project repository</a> and Matrix channel (<a href="https://chat.mozilla.org/#/room/#glean-dictionary:mozilla.org">#glean-dictionary on chat.mozilla.org</a>).</p>iodide retrospectiveurn:https-wrla-ch:-blog-2020-11-iodide-retrospective2020-11-10T14:09:20Z2020-11-10T14:09:20ZWilliam Lachance
<p>A bit belatedly, I thought I’d write a short retrospective on <a href="https://alpha.iodide.io">Iodide</a>: an effort to create a compelling, client-centred scientific notebook environment.</p>
<p>Despite not writing a ton about it (the sole exception being <a href="/blog/2019/03/new-ideas-old-buildings/">this brief essay</a> about my conservative choice for the server backend) Iodide took up a very large chunk of my mental energy from late 2018 through 2019. It was also essentially my only attempt at working on something that was on its way to being an actual <em>product</em> while at Mozilla: while I’ve led other projects that have been interesting and/or impactful in my 9 odd-years here (<a href="https://mozilla.github.io/mozregression/">mozregression</a> and <a href="https://wiki.mozilla.org/EngineeringProductivity/Projects/Perfherder">perfherder</a> being the biggest successes), they fall firmly into the “internal tools supporting another product” category.</p>
<p>At this point it’s probably safe to say that the project has wound down: no one is being paid to work on Iodide and it’s essentially in extreme maintenance mode. Before it’s put to bed altogether, I’d like to write a few notes about its approach, where I think it had big advantanges, and where it seems to fall short. I’ll conclude with some areas I’d like to explore (or would like to see others explore!). I’d like to emphasize that this is <em>my opinion only</em>: the rest of the Iodide core team no doubt have their own thoughts. That said, let’s jump in.</p>
<h2 id="what-is-iodide-anyway">What is Iodide, anyway?</h2>
<p>One thing that’s interesting about a product like Iodide is that people tend to project their hopes and dreams onto it: if you asked any given member of the Iodide team to give a 200 word description of the project, you’d probably get a slightly different answer emphasizing different things. That said, a fair initial approximation of the project vision would be “a scientific notebook like Jupyter, but running in the browser”.</p>
<p>What does this mean? First, let’s talk about what Jupyter does: at heart, it’s basically a Python “kernel” (read: interpreter), fronted by a webserver. You send snipits of the code to the interpreter via a web interface and they would faithfully be run on the backend (either on your local machine in a separate process or a server in the cloud). Results are then be returned back to the web interface and then rendered by the browser in one form or another.</p>
<p>Iodide’s model is quite similar, with one difference: instead of running the kernel in another process or somewhere in the cloud, all the heavy lifting happens <em>in the browser itself</em>, using the local JavaScript and/or WebAssembly runtime. The very first version of the product that Hamilton Ulmer and Brendan Colloran came up with was <em>definitely</em> in this category: it had no server-side component whatsoever.</p>
<p>Truth be told, even applications like Jupyter do a fair amount of computation on the client side to render a user interface and the results of computations: the distinction is not as clear cut as you might think. But in general I think the premise holds: if you load an iodide notebook today (still possible on alpha.iodide.io! no account required), the only thing that comes from the server is a little bit of static JavaScript and a flat file delivered as a JSON payload. All the “magic” of whatever computation you might come up with happens on the client.</p>
<p>Let’s take a quick look at the default tryit iodide notebook to give an idea of what I mean:</p>
<pre><code>%% fetch
// load a js library and a csv file with a fetch cell
js: https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.js
text: csvDataString = https://data.sfgov.org/api/views/5cei-gny5/rows.csv?accessType=DOWNLOAD
%% js
// parse the data using the d3 library (and show the value in the console)
parsedData = d3.csvParse(csvDataString)
%% js
// replace the text in the report element "htmlInMd"
document.getElementById('htmlInMd').innerText = parsedData[0].Address
%% py
# use python to select some of the data
from js import parsedData
[x['Address'] for x in parsedData if x['Lead Remediation'] == 'true']</code></pre>
<p>The <code>%%</code> delimiters indicate individual cells. The <code>fetch</code> cell is an iodide-native cell with its own logic to load the specified resources into a JavaScript variables when evaluated. <code>js</code> and <code>py</code> cells direct the browser to interpret the code inside of them, which causes the DOM to mutate. From these building blocks (and a few others), you can build up an interactive report which can <em>also</em> be freely forked and edited by anyone who cares to.</p>
<p>In some ways, I think Iodide has more in common with services like Glitch or Codepen than with Jupyter. In effect, it’s mostly offering a way to build up a static web page (doing whatever) using web technologies— even if the user interface affordances and cell-based computation model might remind you more of a scientific notebook.</p>
<h2 id="what-works-well-about-this-approach">What works well about this approach</h2>
<p>There’s a few nifty things that come from doing things this way:</p>
<ul>
<li>The environment is easily extensible for those familiar with JavaScript or other client side technologies. There is no need to mess with strange plugin architectures or APIs or conform to the opinions of someone else on what options there are for data visualization and presentation. If you want to use jQuery inside your notebook for a user interface widget, just import it and go!</li>
<li>The architecture scales to many, many users: since all the computation happens on the client, the server’s only role is to store and retrieve notebook content. alpha.iodide.io has happily been running on Heroku’s least expensive dyno type for its entire existence.</li>
<li>Reproducibility: so long as the iodide notebook has no references to data on third party servers with authentiction, there is no stopping someone from being able to reproduce whatever computations led to your results.</li>
<li>Related to reproducibility, it’s easy to <em>build off</em> of someone else’s notebook or exploration, since everything is so self-contained.</li></ul>
<p>I continue to be surprised and impressed with what people come up with in the Jupyter ecosystem so I don’t want to claim these are things that “only Iodide” (or other tools like it) can do— what I will say is that I haven’t seen many things that combine both the conciseness and expressiveness of iomd. The beauty of the web is that there is such an abundance of tutorials and resources to support creating interactive content: when building iodide notebooks, I would freely borrow from resources such as MDN and Stackoverflow, instead of being locked into what the authoring software thinks one should be able express.</p>
<h2 id="whats-awkward">What’s awkward</h2>
<p>Every silver lining has a cloud and (unfortunately) Iodide has a pretty big one. Depending on how you use Iodide, you will almost certainly run into the following problems:</p>
<ul>
<li>You are limited by the computational affordances provided by the browser: there is no obvious way to offload long-running or expensive computations to a cluster of machines using a technology like <a href="https://spark.apache.org/">Spark</a>.</li>
<li>Long-running computations will block the main thread, causing your notebook to become extremely unresponsive for the duration.</li></ul>
<p>The first, I (and most people?) can usually live with. Computers are quite powerful these days and most data tasks I’m interested in are easily within the range of capabilities of my laptop. In the cases where I need to do something larger scale, I’m quite happy to fire up a Jupyter Notebook, BigQuery Console, or <other tool of choice> to do the heavy-lifting, and then move back to a client-side approach to visualize and explore my results.</p>
<p>The second is much harder to deal with, since it means that the process of exploration that is so key to scientific computing. I’m quite happy to wait 5 seconds, 15 seconds, even a minute for a longer-running computation to complete but if I see the slow script dialog and everything about my environment grinds to a halt, it not only blocks my work but causes me to lose faith in the system. How do I know if it’s even going to finish?</p>
<p>This occurs way more often than you might think: even a simple notebook loading pandas (via pyodide) can cause Firefox to pop up the slow script dialog:</p>
<div class="figure"><img src="/files/2020/11/iodide-slow-script.png" alt="" />
<p class="caption"></p></div>
<p>Why is this so? Aren’t browsers complex beasts which can do a million things in parallel these days? Only sort of: while the graphical and network portions of loading and using a web site are highly parallel, JavaScript and any changes to the DOM <em>can only occur synchronously</em> by default. Let’s break down a simple iodide example which trivially hangs the browser:</p>
<pre><code>%% js
while (1) { true }</code></pre>
<p><a href="https://alpha.iodide.io/notebooks/6487/">link</a> (but you really don’t want to)</p>
<p>What’s going on here? When you execute that cell, the web site’s sole thread is now devoted to running that infinite loop. No longer can any other JavaScript-based event handler be run, so for example the text editor (which uses <a href="https://microsoft.github.io/monaco-editor/">Monaco</a> under the hood) and menus are now completely unresponsive.</p>
<p>The iodide team was aware of this issue since I joined the project. There were no end of discussions about how to work around it, but they never really come to a satisfying conclusion. The most obvious solution is to move the cell’s computation to a web worker, but workers don’t have synchronous access to the DOM which is required for web content to work as you’d expect. While there are projects like <a href="https://github.com/GoogleChromeLabs/comlink">ComLink</a> that attempt to bridge this divide, they require both a fair amount of skill and code to use effectively. As mentioned above, one of the key differentiators between iodide and other notebook environments is that tools like jQuery, d3, etc. “just work”. That is, you can take a code snipit off the web and run it inside an iodide notebook: there’s no workaround I’ve been able to find which maintains that behaviour <em>and</em> ensures that the Iodide notebook environment is always responsive.</p>
<p>It took a while for this to really hit home, but having some separation from the project, I’ve come to realize that the problem is that the underlying technology isn’t designed for the task we were asking of it, nor is it likely to ever be in the near future. While the web (by which I mean not only the browser, but the ecosystem of popular tooling and libraries that has been built on top of it) has certainly grown in scope to things it was never envisioned to handle like games and office applications, it’s just not optimized for what I’d call “editable content”. That is, the situation where a web page offers affordances for manipulating its own representation.</p>
<p>While modern web browsers have evolved to (sort of) protect one errant site from bringing the whole thing down, they certainly haven’t evolved to protect a particular site against <em>itself</em>. And why would they? Web developers usually work in the terminal and text editor: the assumption is that if their test code misbehaves, they’ll just kill their tab and start all over again. Application state is persisted either on-disk or inside an external database, so nothing will really be lost.</p>
<p>Could this ever change? Possibly, but I think it would be a radical rethinking of what the web is, and I’m not really sure what would motivate it.</p>
<h2 id="a-way-forward">A way forward</h2>
<p>While working on iodide, we were fond of looking at this diagram, which was taken from <a href="https://dl.acm.org/doi/10.1145/3173574.3173606">this study of the data science workflow</a>:</p>
<div class="figure"><img src="/files/2020/11/ds-workflow.png" alt="" />
<p class="caption"></p></div>
<p>It describes how people typically perform computational inquiry: typically you would poke around with some raw data, run some transformations on it. Only after that process was complete would you start trying to build up a “presentation” of your results to your audience.</p>
<p>Looking back, it’s clear that Iodide’s strong suit was the <em>explanation</em> part of this workflow, rather than collaboration and exploration. My strong suspicion is that we actually want to use different tools for each one of these tasks. Coincidentally, this also maps to the bulk of my experience working with data at Mozilla, using iodide or not: my most successful front-end data visualization projects were typically the distilled result of a very large number of adhoc explorations (python scripts, SQL queries, Jupyter notebooks, …). The actual visualization itself contains very little computational meat: basically “just enough” to let the user engage with the data fruitfully.</p>
<p>Unfortunately much of my work in this area uses semi-sensitive internal Mozilla data so can’t be publicly shared, but here’s one example:</p>
<div class="figure"><img src="/files/2020/11/bq-migration-burndown.png" alt="" />
<p class="caption"></p></div>
<p><a href="https://alpha.iodide.io/notebooks/3593/?viewMode=report">link</a></p>
<p>I built this dashboard in a single day to track our progress (resolved/open bugs) when we were migrating our data platform from AWS to GCP. It was useful: it let us quickly visualize which areas needed more attention and gave upper management more confidence that we were moving closer to our goal. However, there was little computation going on in the client: most of the backend work was happening in our <a href="https://bugzilla.mozilla.org">Bugzilla instance</a>: the iodide notebook just does a little bit of post-processing to visualize the results in a useful way.</p>
<p>Along these lines, I still think there is a place in the world for an interactive <em>visualization</em> environment built on principles similar to iodide: basically a markdown editor augmented with primitives oriented around data exploration (for example, charts and data tables), with allowances to bring in any JavaScript library you might want. However, any in-depth data processing would be assumed to have mostly been run elsewhere, in advance. The editing environment could either be the browser or a code editor running on your local machine, per user preference: in either case, there would not be any really important computational state running in the browser, so things like dynamic reloading (or just closing an errant tab) should not cause the user to lose any work.</p>
<p>This would give you the best of both worlds: you could easily create compelling visualizations that are easy to share and remix at minimal cost (because all the work happens in the browser), but you could <em>also</em> use whatever existing tools work best for your initial data exploration (whether that be JavaScript or the more traditional Python data science stack). And because the new tool has a reduced scope, I think building such an environment would be a much more tractable project for an individual or small group to pursue.</p>
<p>More on this in the future, I hope.</p>
<p><em>Many thanks to <a href="https://teonbrooks.com/">Teon Brooks</a> and Devin Bayly for reviewing an early draft of this post</em></p>mozregression and older buildsurn:https-wrla-ch:-blog-2020-08-mozregression-and-older-builds2020-08-17T19:01:57Z2020-08-17T19:01:57ZWilliam Lachance
<p>Periodically the discussion comes up about pruning away old stored Firefox build artifacts in S3. Each build is tens of megabytes, multiply that by the number of platforms we support and the set of revisions we churn through on a daily basis, and pretty soon you’re talking about real money.</p>
<p>This came up recently in a discussion about <a href="https://groups.google.com/g/mozilla.dev.platform/c/0OV_M3b-cMM/m/kkknfFdECgAJ">removing the legacy taskcluster deployment</a> — what do we actually lose by cutting back our archive of integration builds? The main reason to keep them around is to facilitate bisection testing with <a href="https://mozilla.github.io/mozregression/">mozregression</a>, to find out when a bug was introduced. Up to now, discussions about this have been a bit hand-wavey: we do keep logs about who’s accessing old builds, but it’s never been clear whether it was mozregression accessing them or something else.</p>
<p>Happily, now that <a href="/blog/2020/05/this-week-in-glean-mozregression-telemetry-part-2/">mozregression has some telemetry</a>, it’s a little easier to get some answers on what people are actually doing. This query gets the distribution of build ages (launched or bisected) over the past 6 months, at a month long granularity.<sup><a href="#2020-08-17-mozregression-and-older-builds-footnote-1-definition" name="2020-08-17-mozregression-and-older-builds-footnote-1-return">1</a></sup> Ages are relative to the date mozregression was launched: for example, if someone asked for a build from May 2019 in June 2020, the number would be “13”.</p>
<div class="brush: sql">
<div class="colorful">
<pre><span></span><span class="k">SELECT</span><span class="w"> </span><span class="n">metrics</span><span class="p">.</span><span class="n">string</span><span class="p">.</span><span class="n">usage_app</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">app</span><span class="p">,</span><span class="w"></span>
<span class="w"> </span><span class="n">metrics</span><span class="p">.</span><span class="n">string</span><span class="p">.</span><span class="n">usage_build_type</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">build_type</span><span class="p">,</span><span class="w"></span>
<span class="w"> </span><span class="n">DATE_DIFF</span><span class="p">(</span><span class="nb">DATE</span><span class="p">(</span><span class="n">submission_timestamp</span><span class="p">),</span><span class="w"> </span><span class="k">IF</span><span class="p">(</span><span class="k">LENGTH</span><span class="p">(</span><span class="n">metrics</span><span class="p">.</span><span class="n">datetime</span><span class="p">.</span><span class="n">usage_bad_date</span><span class="p">)</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">PARSE_DATE</span><span class="p">(</span><span class="s1">'%Y-%m-%d'</span><span class="p">,</span><span class="w"> </span><span class="n">substr</span><span class="p">(</span><span class="n">metrics</span><span class="p">.</span><span class="n">datetime</span><span class="p">.</span><span class="n">usage_bad_date</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">10</span><span class="p">)),</span><span class="w"> </span><span class="n">PARSE_DATE</span><span class="p">(</span><span class="s1">'%Y-%m-%d'</span><span class="p">,</span><span class="w"> </span><span class="n">substr</span><span class="p">(</span><span class="n">metrics</span><span class="p">.</span><span class="n">datetime</span><span class="p">.</span><span class="n">usage_launch_date</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">10</span><span class="p">))),</span><span class="w"> </span><span class="k">MONTH</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">build_age</span><span class="w"></span>
<span class="k">FROM</span><span class="w"> </span><span class="o">`</span><span class="n">moz</span><span class="o">-</span><span class="n">fx</span><span class="o">-</span><span class="k">data</span><span class="o">-</span><span class="n">shared</span><span class="o">-</span><span class="n">prod</span><span class="o">`</span><span class="p">.</span><span class="n">org_mozilla_mozregression</span><span class="p">.</span><span class="k">usage</span><span class="w"></span>
<span class="k">WHERE</span><span class="w"> </span><span class="nb">DATE</span><span class="p">(</span><span class="n">submission_timestamp</span><span class="p">)</span><span class="w"> </span><span class="o">>=</span><span class="w"> </span><span class="n">DATE_SUB</span><span class="p">(</span><span class="k">CURRENT_DATE</span><span class="p">(),</span><span class="w"> </span><span class="nb">INTERVAL</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="k">MONTH</span><span class="p">)</span><span class="w"></span>
<span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="n">client_info</span><span class="p">.</span><span class="n">app_display_version</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">LIKE</span><span class="w"> </span><span class="s1">'%dev%'</span><span class="w"></span>
<span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="k">LENGTH</span><span class="p">(</span><span class="n">metrics</span><span class="p">.</span><span class="n">string</span><span class="p">.</span><span class="n">usage_build_type</span><span class="p">)</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mi">0</span><span class="w"></span>
<span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="p">(</span><span class="k">LENGTH</span><span class="p">(</span><span class="n">metrics</span><span class="p">.</span><span class="n">datetime</span><span class="p">.</span><span class="n">usage_bad_date</span><span class="p">)</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mi">0</span><span class="w"></span>
<span class="w"> </span><span class="k">OR</span><span class="w"> </span><span class="k">LENGTH</span><span class="p">(</span><span class="n">metrics</span><span class="p">.</span><span class="n">datetime</span><span class="p">.</span><span class="n">usage_launch_date</span><span class="p">)</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"></span>
</pre></div>
</div>
<p>I ran this query on sql.telemetry.mozilla.org and generated a box plot, broken down by product and build type:</p>
<div class="figure"><img src="/files/2020/08/mozregression-build-age-box-plot.png" alt="" />
<p class="caption"></p></div>
<p><a href="https://sql.telemetry.mozilla.org/queries/73968#184980">link</a> (requires Mozilla LDAP)</p>
<p>Unsurprisingly, Firefox shippable builds are the number one thing people try to bisect. Let’s take a little bit of a closer look at what’s going on there:</p>
<div class="figure"><img src="/files/2020/08/mozregression-build-age-box-plot-detail.png" alt="" />
<p class="caption"></p></div>
<p>The median value is 1, which indicates that most people are bisecting builds within one month of the day in which mozregression was run. And the <a href="https://www.statisticshowto.com/upper-and-lower-fences/">upper fence</a> result is 6, suggesting that most of the time people are looking at a regression range that is within a 6 month range. However, looking more closely at the data points themselves (the little points in the chart above), there are a considerable number of outliers where a range greater than 20 months was asked for.</p>
<p>… which brings up to the question that we want to answer. Given that getting old builds isn’t that common (which we sort of knew already, based on the access patterns in the S3 logs), what is the impact of the times that we do? And it’s here where I have to throw up my hands and say “I don’t know” and suggest that we go back to empirical observation and user research.</p>
<p>You can go back to the thread I linked above, and see that core Firefox/Gecko developers find the ability to get a precise regression range for older revisions valuable. One thing that’s worth mentioning is that mozregression isn’t run that often, compared to a product that we ship: on the order of 50 to 100 times per a day. But when it comes to internal tooling, a small amount of use might have a big impact: if a mozregression invocation a developer a few hours (or more), that’s a real benefit to Firefox and Mozilla. The same argument might apply here, where a small number of bisections on older builds might have a disproportionate impact on the quality of the product.</p>
<div class="footnotes">
<ol>
<li id="2020-08-17-mozregression-and-older-builds-footnote-1-definition" class="footnote-definition">
<p>I only added the telemetry to capture this information <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1651401">relatively recently</a>, so we’re actually only looking at about a month of data in this post. We’ll have more complete results later this year. <a href="#2020-08-17-mozregression-and-older-builds-footnote-1-return">↩</a></p></li></ol></div>