Planet Mozillahttp://planet.mozilla.org/
enPlanet Mozilla - http://planet.mozilla.org/Mark Côté: Lando demohttps://mrcote.info/blog/2018/02/21/lando-demohttps://mrcote.info/blog/2018/02/21/lando-demo/
<p>Lando is so close now that I can practically smell the <a href="https://starwars.wikia.com/wiki/Tibanna">tibanna</a>.
Israel put together a quick demo of Phabricator/BMO/Lando/hg running on
his local system, which is only a few patches away from being a
deployed reality.</p>
<p>One caveat: this demo uses Phabricator’s web UI to post the patch. We
highly recommend using <a href="https://secure.phabricator.com/book/phabricator/article/arcanist/">Arcanist</a>, Phabricator’s command-line tool,
to submit patches instead, mainly because it preserves all the
relevant changeset metadata.</p>
<p>With that out of the way, fasten your cape and take a look:</p>
<p><video controls="true" src="https://mrcote.info/videos/phab-lando-transplant-end-to-end.mp4"></video></p>Thu, 22 Feb 2018 00:20:20 +0000The Mozilla Blog: Snips Uses Rust to Build an Embedded Voice Assistanthttps://blog.mozilla.org/?p=11265https://blog.mozilla.org/blog/2018/02/21/snips-uses-rust-embedded-voice-assistant/
<p>The team at Paris-based <a href="https://snips.ai/" rel="noopener" target="_blank">Snips</a> has created a voice assistant that can be embedded in a single device or used in a home network to control lights, thermostat, music, and more. You can <a href="https://console.snips.ai" rel="noopener" target="_blank">build a home hub</a> on a Raspberry Pi and ask it for a weather report, to play your favorite song, or to brew up a double espresso. Manufacturers like <a href="https://www.keecker.com/us-en" rel="noopener" target="_blank">Keecker</a> are adding Snips’ technology to products like multimedia home robots. And Snips works closely with leaders across the value chain, like NVIDIA, EBV, and Analog Devices, in order to voice-enable an increasingly wider range of device types, from speakers to home automation systems to cars.</p>
<p>Snips’ solution is different from other voice assistants, in that it runs its entire code base on a single device and can work without an Internet connection. Snips’ software stack includes its wake word (“Hey Snips”), application logic, speech recognition engine, and language understanding module.</p>
<p>By comparison, products like Amazon Echo and Google Home just run code for the wake word, and they are dependent on the cloud to process queries and generate responses. That approach opens the door for companies to potentially collect users’ speech data, raising privacy concerns.</p>
<p>How can Snips embed all the code for a voice assistant onto a single device? They wrote it using the Rust systems programming language.</p>
<p>Rust is a highly efficient programming language that was developed in an <a href="https://www.rust-lang.org/en-US/" rel="noopener" target="_blank">open source project</a> and is sponsored by Mozilla. The first stable release of Rust was in <a href="https://en.wikipedia.org/wiki/Rust_(programming_language)" rel="noopener" target="_blank">May 2015</a>. Now, the Rust community is seeing <a href="https://www.rust-lang.org/en-US/friends.html" rel="noopener" target="_blank">companies adopt Rust</a> to build commercial software, often at the cutting edge of their fields.</p>
<p>Rust is compelling because it combines attributes from different kinds of languages, so it can offer high performance and low memory overhead as well as memory safety and cross-compilation to different platforms. That made it a great fit for Snips’ use case: embedding code into a range of device types with limited memory and processing power.</p>
<h3><b>Why Rust?</b></h3>
<p>Snips Principal Engineer <a href="http://www.poumeyrol.fr/" rel="noopener" target="_blank">Mathieu Poumeyrol</a> had used Rust at a previous job, writing multi-platform code. Instead of having to write and then rewrite for each platform, he used Rust’s cross-compilation capability. That let him write once and translate his code so it could run well on different machines, without days or weeks of hand-coding rework.</p>
<p>Poumeyrol pushed hard for Snips to consider adopting Rust. It had the traits Snips needed – efficiency, portability, and safety – and it had the performance characteristics to be able to run wicked fast, even on small devices.</p>
<p>“Snips was already using very modern languages for both mobile development and the back end, like Swift, Kotlin, and Scala,” Poumeyrol said. “That played a big part in convincing our engineers to try Rust.”</p>
<p>After more investigation, the Snips technical team was convinced that Rust was the right way to go. “We went all-in on Rust in 2016,” said Snips CTO Joseph Dureau. “And we are very happy with that decision.”</p>
<h3><b>Performance and Portability</b></h3>
<p>The primary challenge for Snips’ engineering team was this: How can we embed a voice assistant so it runs efficiently and safely on all of our clients’ connected devices, regardless of the operating system and architecture they use?</p>
<p>Rust was the answer to that challenge. The language offered a combination of virtues: the performance of a low-level language like C/C++, the capability to port code to new platforms, and memory safety features designed to enhance security, even when code is running on connected devices that are relatively exposed. (See how <a href="https://knowtechie.com/connected-crock-pot-hotbed-hackers/" rel="noopener" target="_blank">crockpots were hacked</a> in 2016.)</p>
<p><b>Performance: </b>Rust code is fast and efficient. It can run on resource-constrained devices with no degradation in performance. The language manages zero-cost abstraction in the same spirit as C++, Poumeyrol said, while maintaining the same safety level as a language with garbage collection. Rust delivers high-level features without a runtime performance penalty, which was exactly what Snips needed.</p>
<p><b>Portability:</b> Rust’s first-class compiler, rustc, allows Snips’ engineers to write code once and port it to new devices. This is critical, because the company adds new device platforms to its solution every few weeks. Under the hood, rustc is implemented on top of <a href="http://llvm.org/">LLVM</a>, a solid, proven compiler framework. LLVM enables programmers to cross-compile code to most any modern hardware architecture, from mobile devices to desktops and servers.</p>
<p>“We must be able to code once and run our code on many platforms in an optimal and secure way,” Dureau said. “Everything we write for the embedded voice assistant, we write in Rust.”</p>
<p><b>Safety: </b>Rust has a unique ownership model that makes its code, once compiled, safer than C/C++ and easier to maintain over time. The language uses concepts of <em>ownership</em>, <em>moves</em>, and <em>borrows</em> to keep track of memory resources and make sure they are being used appropriately.</p>
<p>Here’s how Rust’s memory safety features work. After programmers write new code, they run it through a compiler. The rustc compiler checks the code for errors. If it finds code that does not handle memory resources correctly, the compile step will not complete. That makes it more difficult to put memory-unsafe code into a production environment. The compiler helps in another way: It gives some feedback about the error alerts, and when possible, suggests fixes. This feedback saves a lot of time and lets new programmers learn by doing, with a lowered risk of introducing security vulnerabilities.</p>
<p>Poumeyrol is a fan of the Rust compiler. “At compilation time, it can make sure the resource management is done correctly, so we have no surprises at runtime,” he said.</p>
<h3><b>One Fast Development Cycle</b></h3>
<p>Working in Rust, the Snips technical team was able to complete its voice platform in record time: It took Snips less than a year to complete the coding work in Rust and put its voice assistant into production.</p>
<p>Memory safety played a large role in accelerating Snips’ development process. The developers could find and fix bugs using feedback from the Rust compiler. Those early corrections made the development cycle much shorter, because it’s simpler to fix bugs early, rather than waiting until runtime. It also speeded up the QA (quality assurance) phase of the process, so Snips was able to move new features into production more quickly.</p>
<p>Snips’ solution currently supports a dozen different device platforms, including the Raspberry Pi 3, DragonBoard, Sagemcom, Jetson TX2, IMX.8M, and others. Rust has made it simpler for the team to extend support to new boards, because they can reuse the same code base rather than writing custom implementations for each architecture.</p>
<h3><b>Learning Rust </b></h3>
<p>Today, all Snips’ embedded code is written in Rust. Over time, Poumeyrol has trained the embedded software engineers to code in Rust, as well as a significant number of the company’s Machine Learning scientists. As they all got more familiar with the language, the team’s go-to reference was the <a href="https://doc.rust-lang.org/book/second-edition/" rel="noopener" target="_blank">second edition</a> of The Rust Programming Language Book, published online by the open source <a href="https://www.rust-lang.org/en-US/" rel="noopener" target="_blank">Rust Project</a>.</p>
<p>The whole training process was fairly quick and organic, Poumeyrol said. The engineers he trained in turn shared their expertise with others, until the entire embedded software engineering team was actively learning the language.</p>
<p>“Rust is a language of its time,” Poumeyrol said. “Once one has a taste for these modern languages, it can be very frustrating to come back to C or C++ when you suddenly need portability and efficiency.” Poumeyrol has seen broad adoption of Rust in the larger industry as well, as software engineers and machine learning scientists see it as a useful tool that can solve persistent coding problems.</p>
<p>The post <a href="https://blog.mozilla.org/blog/2018/02/21/snips-uses-rust-embedded-voice-assistant/" rel="nofollow">Snips Uses Rust to Build an Embedded Voice Assistant</a> appeared first on <a href="https://blog.mozilla.org" rel="nofollow">The Mozilla Blog</a>.</p>Wed, 21 Feb 2018 20:34:56 +0000Judy DeMockerAir Mozilla: The Joy of Coding - Episode 129https://air.mozilla.org/the-joy-of-coding-episode-129/https://air.mozilla.org/the-joy-of-coding-episode-129/
<p>
<img alt="The Joy of Coding - Episode 129" class="wp-post-image" height="90" src="https://air.cdn.mozilla.net/media/cache/cb/68/cb68b6ac48452be7e7f25ddc7b63c959.png" width="160" />
mconley livehacks on real Firefox bugs while thinking aloud.
</p>Wed, 21 Feb 2018 18:00:00 +0000Air MozillaAir Mozilla: Weekly SUMO Community Meeting, 21 Feb 2018https://air.mozilla.org/weekly-sumo-community-meeting-20180221/https://air.mozilla.org/weekly-sumo-community-meeting-20180221/
<p>
<img alt="Weekly SUMO Community Meeting" class="wp-post-image" height="90" src="https://air.cdn.mozilla.net/media/cache/4c/b1/4cb1b015e6a393e53dfc196726ec2561.png" width="160" />
This is the SUMO weekly call
</p>Wed, 21 Feb 2018 17:00:00 +0000Air MozillaQMO: Firefox 59 Beta 10 Testday Resultshttps://quality.mozilla.org/?p=50072https://quality.mozilla.org/2018/02/firefox-59-beta-10-testday-results/
<p><span style="font-weight: 400;">Hello everyone,</span></p>
<p><span style="font-weight: 400;">As you may already know, last Friday – </span><b>February 16nd</b><span style="font-weight: 400;"> – we held a new Testday event, for </span><b>Firefox 59 Beta 10</b><span style="font-weight: 400;">.</span></p>
<p><span style="font-weight: 400;">Thank you </span><i><span style="font-weight: 400;">Mohammed Adam</span></i><span style="font-weight: 400;">, Abhishek Haridass, </span><i><span style="font-weight: 400;"> Fahima Zulfath A</span></i><span style="font-weight: 400;">. and </span><i><span style="font-weight: 400;">Surentharan.R.A.</span></i><span style="font-weight: 400;"> from </span><i><span style="font-weight: 400;"> </span></i><b>India QA Community team </b><span style="font-weight: 400;">for helping us make Mozilla a better place.</span></p>
<p><span style="font-weight: 400;">And special thanks go to the </span><b>Bangladesh QA Community team</b><span style="font-weight: 400;"> for making such a great job and participating in such a large number. These are all the participants: </span><i><span style="font-weight: 400;">Syed Tanvir, Tanvir Mazharu, Sayed Ibn MAsud, Anika Alam, Anamul Hasan, Kazi Ashraf Hossain, Arif, Neaous sharif, Hasibul Hasan Shanto, Hasibul Hasan Abir, Wahid Mohammad Mahfuz, Syed Tanvir, Serajush Salekin, Saheda Reza Antora, Farha, Mehedi Hasan, Habibur Rahman Habib, Sontus Chandra Anik, Md. Zahedul Hossain, Labisa Reza, Foysal Ahmed, Md Solaman Sarif, Md. Rahimul Islam, Abu Sayeed Khan, Hasin Ishrak, Mim Ahmed Joy, Arman, Tanvir Rahman, Md.Jahid Hassan, Emon Ahmed, TIS Salehin, Md Tanvir Hossain, Sajedul Islam, Dibbendu Kumar Sarkar, Masum Billah Musa, Maruf Rahman and Mariya Akter</span></i><span style="font-weight: 400;">. </span></p>
<p><span style="font-weight: 400;">Results:</span></p>
<p><span style="font-weight: 400;">– several test cases executed for </span><b>Find Toolbar </b><span style="font-weight: 400;">and </span><b> Search suggestions</b><span style="font-weight: 400;"> features.</span></p>
<p><span style="font-weight: 400;">– bugs verified: </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=925275"><span style="font-weight: 400;">925275</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1426094"><span style="font-weight: 400;">1426094</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1430391"><span style="font-weight: 400;">1430391</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1228111"><span style="font-weight: 400;">1228111</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1430773"><span style="font-weight: 400;">1430773</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1115976"><span style="font-weight: 400;">1115976</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=989642"><span style="font-weight: 400;">989642</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1436110"><span style="font-weight: 400;">1436110</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1420601"><span style="font-weight: 400;">1420601</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1426920"><span style="font-weight: 400;">1426920</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1436876"><span style="font-weight: 400;">1436876</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1430143"><span style="font-weight: 400;">1430143</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1429974"><span style="font-weight: 400;">1429974</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1338497"><span style="font-weight: 400;">1338497</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1435838"><span style="font-weight: 400;">1435838</span></a><span style="font-weight: 400;">, </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1038695"><span style="font-weight: 400;">1038695</span></a></p>
<p><span style="font-weight: 400;">Thanks for another successful testday <img alt="🙂" class="wp-smiley" src="https://s.w.org/images/core/emoji/2.4/72x72/1f642.png" style="height: 1em;" /></span></p>
<p><span style="font-weight: 400;">We hope to see you all in our next events, all the details will be posted on QMO!</span></p>Wed, 21 Feb 2018 06:53:40 +0000Cornel IonceDavid Humphrey: What Happens when you Contribute, revisited5a8c781e7bee6a03d4f541f3https://blog.humphd.org/what-happens-when-you-contribute-revisited/
<div class="kg-card-markdown"><p>I sat down to write a post about my students' experiences this term contributing to open source, and apparently I've <a href="https://blog.humphd.org/what-happens-when-you-contribute/">written this before</a> (and almost exactly a year ago to the day!) The thing about teaching is that it's cyclic, so you'll have to forgive me as I give a similar lecture here today.</p>
<p>I'm teaching two classes on open source development right now, two sections in an introductory course, and another two in a follow-up intermediate course. The students are just starting to get some releases submitted, and I've been going through their blogs, pull requests, videos (apparently this generation likes making videos, which is something new for me), tweets, and the like. I learn a lot from my students, and I wanted to share some of what I'm seeing.</p>
<p>Most of what I'm going to say is aimed at maintainers and existing open source developers; I'm talking to myself as much as anyone. Because the students go out and work on real open source bugs in all different projects, anything can and does happen. I can't easily prepare them for the responses they'll encounter when they put themselves out there on the web: I see it all.</p>
<p>When you work on (i.e., specialize, focus on) a few projects, and within a particular community, it's easy to get lulled into normalizing all sorts of behaviour that may or may not be the most productive way to work. However, when you participate in a lot of different projects, you start to see that there are a many different approaches, each with varying degrees of positive and negative outcomes.</p>
<p>I wanted to lay before you the kinds of things I've seen this month. I'm not going to link to anything or anyone in particular. Rather, I want to show you the variety of possible scenarios when someone contributes to an open source project. For the most part, these students are at a similar level (i.e., undergraduate CS) and doing similar sorts of patches: first contribution to a project of small doc/test/code fixes, ~100 or fewer lines of code.</p>
<ul>
<li>
<p><em>...crickets...</em>. It's really common for PRs to just get completely ignored. Sometimes this happens because students contribute to dead or dying projects, other times the maintainers just can't be bothered. I try to intervene before this happens, but even I can't always predict how submissions will be received (I had a big PR get rejected like this recently). Looks can be deceiving, and a lot of projects look more active than they are. I deal with this by marking the content/process of a change vs. its reception/outcome.</p>
</li>
<li>
<p><code>"LGTM, merged"</code>. A lot of times the code is correct, the expected process has been followed, and the PR is merged as is. There isn't a lot of criticism, but there also isn't a lot of fanfare. It's likely the 100th PR this maintainer has merged in recent weeks, and it's just another day at the office. This is pretty typical. I think it's OK, but it misses the chance to further engage someone new in your community. I wish GitHub did more to signal in a PR that this is someone's first work. That said, I think most maintainers know when a new person arrives on the scene. Take a minute to welcome them, say "thank you", and if you're smart, point them at follow up bugs to fix.</p>
</li>
<li>
<p><code>"I don't want this change, closing"</code>. I've seen a bunch of this recently. Students are often surprised by this, because there was a bug filed, and it looked like the change/feature was wanted. However, I'm not surprised, because most projects don't triage their bugs anymore. It's becoming increasingly difficult to look at the issues in a project and know whether or not you should tackle them. I have sympathy for both sides. I'm trying to teach students to communicate in bugs before they start working. Some do; a lot feel intimidated to expose themselves until they are sure they can fix the bug, so they start with the fix before announcing their presence. Even if you ask in a bug, a lot of projects won't respond to questions, only PRs, so it's a catch-22.</p>
</li>
<li>
<p><code>"Thanks, but we need to do this differently"</code>. Here you have a PR that "fixes" a bug, and a maintainer that wants it done another way. I would say that this is the expected result of a PR in 95% of cases--you always need review to catch things. However, at this point there are a few scenarios that can happen, not all of them desirable:</p>
</li>
</ul>
<ol>
<li>review comments in the PR lead to follow-up work by the student in order to create the desired code</li>
<li>the maintainer sends a PR to the student's repo/branch with some changes</li>
<li>the maintainer just does it on their own in a new commit, closes the student's PR</li>
</ol>
<p>I see all of these happen regularly. Not every open source project is a collaborative project, and I spend a lot of time these days trying to steer students toward and away from certain communities. There's no point spending time on a project that doesn't want your involvement. The projects that do this well take a raw, inexperienced contributor and encourage them to grow, and in so doing, help to invest in the future health of the project: "if you can fix this bug, you can fix <em>these</em> bugs too..."</p>
<ul>
<li>
<p><code>"This is great! While you're fixing this, can you also fix this other related bug?"</code> This is a great way to draw contributors deeper into a project. Often it means assigning them new bugs (i.e., not adding to the current PR) and expanding their involvement in the code. I've seen this go very well a lot of times across many projects. To be honest, I don't know why more maintainers don't just assign people bugs (I do it all the time). The worst that will happen is that people will say "no," or simply ignore the request. In many cases, though, I find that people step up and enjoy the responsibility and inclusion. What you're really saying is "I think you can do this," and people need to hear that.</p>
</li>
<li>
<p><code>"Thank you for this fix! We've made you a collaborator"</code>. I'm aware that this approach won't work for every project (e.g., security issues). But I see many projects doing it, and it's a fascinating approach. When someone shows up and is both willing and able to contribute, why not make them part of your core group? This week I saw one of my students not only fix bugs in a big project, bug also get contrib rights and assigned other bugs to review. That's an incredible gesture of confidence and inclusion.</p>
</li>
<li>
<p><code>"We really appreciated your contribution, here's a thank-you"</code>. When it happens, it's nice, and I saw it happen a few times this week. It can take a few forms, for example, sending people swag. This is beyond the reach of lots of projects, since it has a real-world cost for the swag, shipping, the time of the person co-ordinating it. For projects that can't send a physical thank-you, there are other ways. For example, I see prominent people/projects in the open source world use their social media presence to draw attention to contributor work. It means a lot to have someone you respect in a project take the time to thank you publicly, or to highlight your contribution. These acts build gratitude into your community, and help to encourage people to keep going.</p>
</li>
<li>
<p><code>"Why don't we pair program on bugs sometime."</code> A few senior people have reached out to students contributing patches and suggested they work together in real-time. In one case that meant having the student go into their office and meeting in real life. In a few other cases it meant using remote screen sharing apps and video conferencing. What an amazing thing to spend time helping to level-up a committed contributor, and what a sign of confidence for someone who is feeling like an imposter working with so many advanced developers.</p>
</li>
</ul>
<p>Even though it doesn't always go smoothly, I'm still a big believer in having students work on real bugs. Every interaction with the open source community is a learning opportunity, even if all it does is teach you that you don't want to do it again. Thankfully, that's not usually what happens, and even after 15 years of this, I'm still seeing new things I can't predict.</p>
<p>If you're an open source dev or maintainer, I'd encourage you to try submitting some PRs to a project you've never worked on before. You'll be surprised at the hoops you have to go through (they always seem more sane on your own projects), how you feel waiting on a delayed response to your fix, and seeing how you're treated outside your home turf. To keep myself honest and aware of this, I try to contribute fixes to lots of new projects. It's very humbling. Thankfully, if you've lost touch with what it's like to be new, just go fix a bug in a project you don't know using a technology you've never seen before. You'll learn a lot, not least about yourself, and it might affect how you respond to people in your own projects.</p>
<p>Anyway, I'm sure I'll forget I've written this post again and rewrite it next year. Until then.</p>
</div>Tue, 20 Feb 2018 21:11:29 +0000David HumphreyThe Firefox Frontier: Share Exactly What You See On-Screen With Firefox Screenshotshttps://blog.mozilla.org/firefox/?p=661https://blog.mozilla.org/firefox/share-exactly-see-screen-firefox-screenshots/
<p>A “screenshot” is created when you capture what’s on your computer screen, so you can save it as a reference, put it in a document, or send it as an … <a class="go" href="https://blog.mozilla.org/firefox/share-exactly-see-screen-firefox-screenshots/">Read more</a></p>
<p>The post <a href="https://blog.mozilla.org/firefox/share-exactly-see-screen-firefox-screenshots/" rel="nofollow">Share Exactly What You See On-Screen With Firefox Screenshots</a> appeared first on <a href="https://blog.mozilla.org/firefox" rel="nofollow">The Firefox Frontier</a>.</p>Tue, 20 Feb 2018 18:58:10 +0000The Mozilla Blog: 20 Big Ideas to Connect the Unconnectedhttps://blog.mozilla.org/?p=11255https://blog.mozilla.org/blog/2018/02/20/20-big-ideas-connect-unconnected/
<h4><i>The National Science Foundation and Mozilla are supporting projects that keep the web accessible, decentralized, and resilient</i></h4>
<p> </p>
<p>Last year, the National Science Foundation (NSF) and Mozilla announced the <a href="https://wirelesschallenge.mozilla.org/">Wireless Innovation for a Networked Society (WINS) challenges</a>: $2 million in prizes for big ideas to connect the unconnected across the U.S.</p>
<p>Today, we’re announcing our first set of winners: 20 bright ideas from Detroit, Cleveland, Albuquerque, New York City, and beyond. The winners are building mesh networks, solar-powered Wi-Fi, and network infrastructure that fits inside a single backpack. Winning projects were developed by veteran researchers, enterprising college students, and everyone in-between.</p>
<p>What do all these projects have in common? They’re affordable, scalable, open-source, and secure.</p>
<p>“Some <a href="https://www.fcc.gov/reports-research/reports/broadband-progress-reports/2016-broadband-progress-report">34 million Americans</a> — many of them located in rural communities and on tribal lands — lack high-quality Internet access,” says Jim Kurose, Assistant Director of NSF for Computer and Information Science and Engineering (CISE). “By supporting ideas like the ones that have surfaced through the WINS challenges, Internet access could be expanded to potentially millions of Americans, enabling many social and economic opportunities that come with connectivity.”</p>
<p>“As the value of being connected to the Internet steadily increases, Americans without affordable access to the net are increasingly excluded from a world of social, educational, and economic possibility,” adds Mozilla Fellow and WINS judge Steve Song. “The 20 projects short-listed are evidence of the potential that now exists for thoughtful, committed citizens to build affordable, scalable, secure communication infrastructure wherever it is needed.”</p>
<p>The 20 Stage 1 winners presented rigorously-researched design concepts and will receive between $10,000 and $60,000 each. Winners were selected by a panel of judges from organizations like Nokia, Columbia University, and the Raspberry Pi Foundation.</p>
<p>Up next: All winning teams — along with more than 100 other WINS submissions — are now invited to build working prototypes as part of the second stage of the competition. In August, these finalists will provide live demonstrations of their prototypes at an event in Mountain View, CA. Final awards, ranging from $50,000 to $400,000, will be announced in the fall of 2018.</p>
<p> </p>
<h3><b>OFF THE GRID INTERNET CHALLENGE WINNERS</b></h3>
<p><i>When disasters strike, communications networks are among the first pieces of critical infrastructure to overload or fail. These 10 creative ideas being recognized with design prizes leverage both the internet’s decentralized design and current wireless technology to keep people connected to each other — and to vital messaging and mapping services — in the aftermath of earthquakes, hurricanes, and other disasters.</i></p>
<div class="wp-caption alignright" id="attachment_11262"><img alt="" class="wp-image-11262 size-medium" height="163" src="https://blog.mozilla.org/wp-content/uploads/2018/02/PL-300x163.png" width="300" /><p class="wp-caption-text">A schematic of Project Lantern | courtesy of Paper &amp; Equator</p></div>
<p><b>[1] Project Lantern | First Place ($60,000) </b>A Lantern is a keychain-sized device that hosts decentralized web apps with local maps, supply locations, and more. These apps are pushed to Lanterns via long-range radio and Wi-Fi, and then saved offline to browsers for continued use. Lanterns can be distributed by emergency responders and are accessed by citizens through a special-purpose Wi-Fi network supported by the Lanterns. Project by Paper &amp; Equator in New York, NY in collaboration with the Shared Reality Lab at McGill University; <a href="https://medium.com/read-write-participate/an-internet-that-fits-on-your-keychain-ae582d8bcd48">learn more</a>.</p>
<div class="wp-caption alignright" id="attachment_11259"><img alt="" class="size-medium wp-image-11259" height="200" src="https://blog.mozilla.org/wp-content/uploads/2018/02/HERMES-1-300x200.jpg" width="300" /><p class="wp-caption-text">Hardware components for HERMES | courtesy of Rhizomatica</p></div>
<p><b>[2] HERMES | Second Place ($40,000) </b>HERMES (High­-frequency Emergency and Rural Multimedia Exchange System) is autonomous network infrastructure. It enables local calling, SMS, and basic OTT messaging, all via equipment that can fit inside two suitcases, using GSM, Software Defined Radio and High-Frequency radio technologies. Project by Rhizomatica.</p>
<p><b>[3] Emergency LTE | Third Place ($30,000) </b>Emergency LTE is an open-source, solar- and battery-powered cellular base station that functions like an autonomous LTE network. The under-50-pound unit features a local web server with apps that allow emergency broadcasts, maps, messaging, and more. Project lead: Dr. Spencer Sevilla in Seattle, WA.</p>
<p><b>[4] The Next­-Generation, Disaster Relief Mobile Phone Mesh Network | Honorable Mention ($10,000) </b>This project provides a phone­-to-­phone mesh network that’s always on, even if all other systems are offline. A goTenna Mesh device unlocks connectivity using ISM radio bands, then pairs with Android and iOS phones to provide messaging and mapping, as well as back-haul connectivity when available. Project by goTenna in Brooklyn, NY;<a href="http://imeshyou.com"> see the network map here</a> &amp;<a href="https://gotenna.com/"> learn more</a>.</p>
<p><b>[5] G.W.N. | Honorable Mention ($10,000) </b>G.W.N. (Gridless Wireless Network) leverages ISM radio bands, Wi-Fi modules, and antennae to provide connectivity. When users connect to these durable 10-pound nodes, they can locate nearby shelters or alert emergency responders. Project lead: Dr. Alan Mickelson in Boulder, CO; <a href="https://github.com/jilu7883/Off_The_Grid">learn more</a>.</p>
<p><b>[6] Wind: Off­-Grid Services for Everyday People | Honorable Mention ($10,000) </b>Wind uses Bluetooth, Wi-Fi Direct, and physical infrastructure nodes built from common routers to create a peer-to-peer network. The project also features a decentralized software and content distribution system. By Guardian Project in New York; <a href="https://guardianproject.info/wind/">learn more</a>.</p>
<p><b>[7] Baculus | Honorable Mention ($10,000) </b>Baculus features a telescoping antennae/flag, a Wi-Fi access point, small computer, GPS transceiver, software defined radio, and battery, all housed inside a rolling backpack. The project provides applications like maps and message boards over an ad-hoc, self-repairing Wi-Fi network. Project Lead: Jonathan Dahan in New York; Design Lead: Ariel Cotton;<a href="http://jedahan.com/baculus/"> learn more</a>.</p>
<p><b>[8] Portable Cell Initiative | Honorable Mention ($10,000) </b>This project deploys a “microcell,” or temporary cell tower, in the aftermath of a disaster. The project uses software defined radio (SDR) and a satellite modem to enable voice calls, SMS, and data services. It also networks with nearby microcells. Project lead: Arpad Kovesdy in Los Angeles, CA; <a href="https://github.com/Ironarcher/portable-cell-initiative">learn more</a>.</p>
<p><b>[9] Othernet Relief Ecosystem | Honorable Mention ($10,000) </b>Othernet Relief Ecosystem (O.R.E.) is an extension of Dhruv’s Othernet installations in Brooklyn, NY. These installations stem from a long tradition of mesh networking wherein the OpenWRT firmware alongside the B.A.T.M.A.N. protocol run on Ubiquiti hardware to form large-­scale local area networks. Each island of connectivity can be connected to each other using point-to-point antennas. A toolset of lightweight applications can live on these networks. Project lead: Dhruv Mehrotra in New York, NY; <a href="http://othernet.xyz/">learn more</a>.</p>
<p><b>[10] RAVE | Honorable Mention ($10,000) </b>RAVE (Radio­-Aware Voice Engine) a push-to-talk mobile application providing high-fidelity audio communication via a peer-to-peer Bluetooth or Wi-Fi connection. Multiple RAVE devices form a multi-hop network capable of extending communication over longer distances. RAVE’s range can be extended via a network of relay nodes. These inexpensive, battery-powered devices automatically set up a mesh network that extends real-time voice and internet access throughout a whole community, and text communication over several miles. Project by Throneless in Washington, D.C.; <a href="https://commotionwireless.github.io/rave/">learn more</a>.</p>
<p> </p>
<h3><b>SMART COMMUNITY NETWORKS CHALLENGE WINNERS</b></h3>
<p><i>Many communities across the U.S. lack reliable internet access. Sometimes commercial providers don’t supply affordable access; sometimes a particular community is too isolated; sometimes the speed and quality of access is too slow. These 10 creative ideas being recognized with design prizes aim to leverage existing infrastructure — physical or network — to provide high-quality wireless connectivity to communities in need.</i></p>
<div class="wp-caption alignright" id="attachment_11260"><img alt="" class="size-medium wp-image-11260" height="375" src="https://blog.mozilla.org/wp-content/uploads/2018/02/EII-1-300x375.jpg" width="300" /><p class="wp-caption-text">An EII installation | courtesy of the Detroit Community Technology Project</p></div>
<p><b>[11] Equitable Internet Initiative (EII) | First Place ($60,000) </b>EII uses a system of relays to beam wireless broadband from a local ISP to vulnerable neighborhoods. The system includes solar-powered batteries, an intranet with apps, and training so local users can build and maintain the network. By the Detroit Community Technology Project, sponsored by Allied Media Projects in Detroit, MI;<a href="https://medium.com/read-write-participate/connecting-the-unconnected-in-detroit-f56790bea8e0"> learn more</a>.</p>
<p> </p>
<p><b>[12] NoogaNet | Second Place ($40,000) </b>NoogaNet provides wireless access within a defined neighborhood by leveraging utility pole-­mounted Wi-Fi nodes, point­-to-­multipoint millimeter wave, and mesh technologies. The project also includes user training for installing, utilizing, and managing a wireless mesh node. Project by the Enterprise Center in Chattanooga, TN; <a href="https://www.theenterprisectr.org/">learn more</a>.</p>
<p><b>[13] Southern Connected Communities Network | Third Place ($30,000) </b>This project entails a broadband tower — and eventually, series of towers — that can deliver 1-Gbps speeds wirelessly to anyone in a 25-mile radius via public spectrums. The towers will be controlled by community members in rural Appalachia and the South who are currently underserved by major ISPs. Project by the Highlander Research and Education Center in New Market, TN.</p>
<p><b>[14] Solar Mesh | Honorable Mention ($10,000) </b>This project integrates mesh Wi-Fi access points into solar-powered light poles in order to provide connectivity to low-income households. The bandwidth is provided by T­Mobile. Project by the San Antonio Housing Authority in TX.</p>
<p><b>[15] Connect the Unconnected | Honorable Mention ($10,000) </b>Using a fixed wireless backbone network, this project provides public housing and homeless shelter residents in a two-­square-mile radius with connectivity at speeds up to 35 Mb/s using point-to-point and point-to-multipoint millimeter wave technology. Residents also receive digital literacy training on refurbished devices that they are permitted to keep upon graduation. Project by DigitalC in Cleveland, OH.</p>
<p><b>[16] Repairable Community Cellular Networks­ | Honorable Mention ($10,000) </b>This project equips residents with sensors and software to carry out basic repairs and precautionary measures on OpenCellular base stations. The goal: decrease the likelihood and duration of service interruptions<i>. </i>Project by University of Washington in Seattle; <a href="https://github.com/infrared0/ccm-rural-repair">learn more</a>.</p>
<p><b>[17] People’s Open Network | Honorable Mention ($10,000) </b>The People’s Open Network uses off-­the-­shelf multi­band Wi-Fi hardware and custom open-source software to connect and automatically route internet traffic from apartment to apartment and house to house in a decentralized manner<i>. </i>Project by sudomesh in Oakland, CA; <a href="https://peoplesopen.net/">learn more</a>.</p>
<p><b>[18] BarelasGig | Honorable Mention ($10,000) </b>This project uses modern millimeter wave (mmW) technology to provide wireless gigabit backhaul and last-mile connectivity at a fraction of the cost of full fiber deployment<i>. </i>Project lead: Michael Sanchez in Albuquerque, NM.</p>
<p><b>[19] NYC Mesh Community Network | Honorable Mention ($10,000) </b>This project uses high-­bandwidth sector antennas, internet exchange points, mesh protocols, and solar batteries to create a community-owned, decentralized network<i>. </i>Project by NYC Mesh in New York City, NY; <a href="https://nycmesh.net/">learn more</a>.</p>
<p><b>[20] Telehub 2.0 ­- DuBois MAN | Honorable Mention ($10,000) </b>This project provides wireless connectivity to underserved neighborhoods and school districts through radio infrastructure mounted on light poles. The project also features educational-technology initiatives to improve academic performance<i>. </i>Project by W.E.B. DuBois Learning Center in Kansas City, MO; <a href="http://www.duboislc.org/Telehub/T2/Smart-City">learn more</a>.</p>
<p>The post <a href="https://blog.mozilla.org/blog/2018/02/20/20-big-ideas-connect-unconnected/" rel="nofollow">20 Big Ideas to Connect the Unconnected</a> appeared first on <a href="https://blog.mozilla.org" rel="nofollow">The Mozilla Blog</a>.</p>Tue, 20 Feb 2018 14:00:03 +0000MozillaDaniel Pocock: Hacking at EPFL Toastmasters, Lausanne, tonight359 at https://danielpocock.comhttps://danielpocock.com/hacking-at-epfl-tonight-2018-02-20
<div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>As mentioned in my <a href="https://danielpocock.com/talking-about-hacking-toastmasters-epfl-2018-02-20">earlier blog</a>, I give a talk about Hacking at the Toastmasters club at EPFL tonight. Please feel free to <a href="https://danielpocock.com/talking-about-hacking-toastmasters-epfl-2018-02-20">join us</a> and remember to turn off your mobile device or leave it at home, you never know when it might ring or become part of a demonstration.</p>
</div></div></div>Tue, 20 Feb 2018 11:39:29 +0000Daniel.PocockAndy McKay: Bugzilla Triage Helperhttp://www.agmweb.ca/bugzilla-triage-helperhttp://www.agmweb.ca/2018-02-20-bugzilla-triage-helper/
<p>In the process of shipping Firefox 57, we found a couple of things out about bugs and Bugzilla. </p>
<p><img src="https://addons.cdn.mozilla.net/user-media/previews/full/197/197451.png?modified=1518215572" style="float: right;" /> </p>
<p>There are an awful lot of bugs filed against Firefox and all it's components in the course of a release. Keeping on top of that is hard and some teams have adopted some policies to help with that (for example see: design-decision-needed).</p>
<p>Having a consistent approach to bugs across the organisation makes it a little easier for everyone to get a feel for what's going. </p>
<p>Sometimes the burden of setting all the right values can be tiring and prone to error. For example: setting a bug to P1 could involve the following:</p>
<ul>
<li>changing the priority</li>
<li>setting the right flag for Firefox version</li>
<li>changing the status</li>
<li>turning off the cc flag</li>
<li>setting a whiteboard value</li>
</ul>
<p>In Austin, we had a chat about this and it was suggested we make a tool to provide a consistent approach to this. A few weeks later I threw Bugzilla Triage Helper onto <a href="https://github.com/andymckay/bugzilla-triage-helper">Github</a> and <a href="https://addons.mozilla.org/en-US/firefox/addon/bugzilla-triage-helper/">addons.mozilla.org</a>. This tool is a content script that inserts an overlay onto Bugzilla.</p>
<p>This gives you a simple button (or keyboard shortcut) that does all of the above. It will even submit the bug for you so you can get on to the next bug.</p>
<p>Of course, it turns out that everyone's workflow is slightly different. So I recently added the ability to add "additional" actions. These are dynamically looked by the product and component. They are specified in JS in the repo, so triage owners who want a slightly different wrinkle on the flow can alter that on github.</p>
<p>Some examples: </p>
<ul>
<li>one team sets a blocking bug number of each bug that blocks release, so they've extended P1 to do that.</li>
<li>one team has 5 or 6 common replies asking for more information and informing the user on how to get that information. So they've extended the "Canned" response option to select those.</li>
</ul>
<p>The extension is a content script that alters the DOM, which means its full of icky DOM code to manipulate the UI. I could do this through the API, but there's a couple of reasons I do it in the UI:</p>
<ul>
<li>I really don't want to build a new UI to Bugzilla</li>
<li>most people triaging are looking at the bug in the UI</li>
<li>a user might want to add more to the bug not captured in the tool in ad hoc process</li>
<li>Bugzilla has lots of things like mid-air collision detection, recursive blocking and so on that are surfaced in the UI</li>
<li>see the first point again</li>
</ul>
<p>At this point I'm starting to use it in some triages and I hope others will too and give me some feedback or even better some patches.</p>Tue, 20 Feb 2018 08:00:00 +0000This Week In Rust: This Week in Rust 222tag:this-week-in-rust.org,2018-02-20:blog/2018/02/20/this-week-in-rust-222/https://this-week-in-rust.org/blog/2018/02/20/this-week-in-rust-222/
<p>Hello and welcome to another issue of <em>This Week in Rust</em>!
<a href="http://rust-lang.org">Rust</a> is a systems language pursuing the trifecta: safety, concurrency, and speed.
This is a weekly summary of its progress and community.
Want something mentioned? Tweet us at <a href="https://twitter.com/ThisWeekInRust">@ThisWeekInRust</a> or <a href="https://github.com/cmr/this-week-in-rust">send us a pull request</a>.
Want to get involved? <a href="https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md">We love contributions</a>.</p>
<p><em>This Week in Rust</em> is openly developed <a href="https://github.com/cmr/this-week-in-rust">on GitHub</a>.
If you find any errors in this week's issue, <a href="https://github.com/cmr/this-week-in-rust/pulls">please submit a PR</a>.</p>
<h3>Updates from Rust Community</h3>
<h4>News &amp; Blog Posts</h4>
<ul>
<li>🎈🎉 <a href="https://blog.rust-lang.org/2018/02/15/Rust-1.24.html">Announcing Rust 1.24</a>. 🎉🎈</li>
<li><a href="https://github.com/rayon-rs/rayon">Rayon 1.0 is released</a>.</li>
<li><a href="https://github.com/quicktype/quicktype/pull/512">Initial support for Rust has landed in quicktype</a>. quicktype generates types and converters from JSON.</li>
<li><a href="https://internals.rust-lang.org/t/rust-team-structure-revamp/6776">Announcement: Rust team structure revamp</a>.</li>
<li><a href="http://blog.japaric.io/stack-overflow-protection/">Embedded Rust: Zero cost stack overflow protection for ARM Cortex-M devices</a>.</li>
<li><a href="https://exyr.org/2018/rust-arenas-vs-dropck/">Borrow cycles in Rust: arenas v.s. drop-checking</a>.</li>
<li><a href="https://udoprog.github.io/rust/2018-02-19/porting-rust-to-wasm.html">Porting Rust to WebAssembly</a>.</li>
<li><a href="https://llogiq.github.io/2018/02/14/mutagen.html">Mutation testing Rust in earnest</a>.</li>
<li><a href="http://words.steveklabnik.com/the-expressive-c-17-coding-challenge-in-rust-revisited">“The expressive C++17 coding challenge (in Rust)” revisited</a>.</li>
<li><a href="http://phaazon.net/blog/spectra_plugins">Write a plugin system and script your app in Rust</a>.</li>
<li><a href="https://medium.com/@spyr1014/sorting-in-rust-selection-insertion-and-counting-sort-2c4d3575e364">Sorting in Rust: selection, insertion, and counting sort</a>.</li>
<li><a href="https://eno.space/blog/2018/02/Ferrous-oxide-for-jaguars-and-incremented-crocodiles">Learning Rust: A small set of pitfalls a novice might encounter, and how to avoid them</a>.</li>
<li><a href="https://guillaumegomez.github.io/this-week-in-rust-docs/blog/this-week-in-rust-docs-93">This week in Rust docs 93</a>.</li>
<li>[podcast] <a href="https://rusty-spike.blubrry.net/2018/02/15/episode-19-feb-14-2018/">Rusty Spike Podcast - episode 19</a>. new teams, humble bundle, SIMD, being special, quicktype, and deps.rs.</li>
</ul>
<h3>Crate of the Week</h3>
<p>This week's crate is <a href="https://github.com/rust-fuzz/afl.rs">afl.rs</a>, a by now pretty well-known fuzzing tool for Rust. Thanks to <a href="https://users.rust-lang.org/u/phansch">Philipp Hansch</a> for the suggestion.</p>
<p><a href="https://users.rust-lang.org/t/crate-of-the-week/2704">Submit your suggestions and votes for next week</a>!</p>
<h3>Call for Participation</h3>
<p>Always wanted to contribute to open-source projects but didn't know where to start?
Every week we highlight some tasks from the Rust community for you to pick and get started!</p>
<p>Some of these tasks may also have mentors available, visit the task page for more information.</p>
<ul>
<li><a href="https://www.rustaceans.org/findwork/starters">Get started with these beginner-friendly issues</a>.</li>
<li><a href="https://github.com/llogiq/mutagen/issues">Mutagen: A mutation testing framework</a> needs help with some beginner-friendly issues.</li>
<li>[good first issue] <a href="https://github.com/lfairy/rust-errno/issues/14">errno: Port library to winapi 0.3</a>.</li>
</ul>
<p>If you are a Rust project owner and are looking for contributors, please submit tasks <a href="https://users.rust-lang.org/t/twir-call-for-participation/4821">here</a>.</p>
<h3>Updates from Rust Core</h3>
<p>95 pull requests were <a href="https://github.com/search?q=is%3Apr+org%3Arust-lang+is%3Amerged+merged%3A2017-02-12..2018-02-19">merged in the last week</a></p>
<ul>
<li><a href="https://github.com/rust-lang/rust/pull/47408">don't promote the result of dereferences to <code>'static</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48163">rustc: persist LLVM's <code>Linker</code> in Fat LTO</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48181">incr.comp.: run cache directory garbage collection before loading dep-graph</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48154">continue parsing function after finding <code>...</code> arg</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48167">remove allocation from width of character function</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48005">unimplement Send/Sync for ::env::{Args,ArgsOs,Vars,VarsOs}</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/45404">support <code>default impl</code> for specialization</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47687"><code>PanicInfo</code> and <code>Location</code> API changes</a> (RFC #2070)</li>
<li><a href="https://github.com/rust-lang/rust/pull/48065">optimize <code>Vec::retain</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48035">early exit for empty HashMap</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48087">add <code>Range(Inclusive)::is_empty</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48156">add <code>std</code>/<code>core::iter::repeat_with</code></a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/5029"><code>cargo new</code> defaults to bin</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/5037">cargo conflict tracking</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48274">remove hoedown from rustdoc</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48144">compiletest: delete the compiled program once its test is done</a></li>
</ul>
<p>And my personal favourite:</p>
<ul>
<li><a href="https://github.com/rust-lang/rust/pull/47956">this is the ideal FileType on Windows. You may not like it, but this is what peak performance looks like</a></li>
</ul>
<h4>New Contributors</h4>
<ul>
<li>Alex Crawford</li>
<li>Antoni Boucher</li>
<li>Artyom Pavlov</li>
<li>Brad Gibson</li>
<li>Jacob Hughes</li>
<li>Mazdak Farrokhzad</li>
<li>Paolo Teti</li>
<li>Pramod Bisht</li>
<li>roblabla</li>
<li>Ross Light</li>
<li>Shaun Steenkamp</li>
</ul>
<h4>Approved RFCs</h4>
<p>Changes to Rust follow the Rust <a href="https://github.com/rust-lang/rfcs#rust-rfcs">RFC (request for comments)
process</a>. These
are the RFCs that were approved for implementation this week:</p>
<ul>
<li><a href="https://github.com/rust-lang/rfcs/pull/2195">RFC 2195: Formally define repr(u32, i8, etc...) and repr(C) on enums with payloads</a>.</li>
<li><a href="https://github.com/rust-lang/rfcs/pull/2056">RFC 2056: Allow trivial constraints to appear in where clauses</a>.</li>
<li><a href="https://github.com/rust-lang/rfcs/pull/2175">RFC 2175: or-patterns in if / while let expressions</a>.</li>
<li><a href="https://github.com/rust-lang/rfcs/pull/2166">RFC 2166: impl-only-use</a>. The <code>use …::{… as …}</code> syntax can now accept <code>_</code> as alias to a trait to only import the implementations of such a trait.</li>
<li><a href="https://github.com/rust-lang/rfcs/pull/2299">Issues are not feature requests</a>.</li>
</ul>
<h4>Final Comment Period</h4>
<p>Every week <a href="https://www.rust-lang.org/team.html">the team</a> announces the
'final comment period' for RFCs and key PRs which are reaching a
decision. Express your opinions now. <a href="https://github.com/rust-lang/rfcs/labels/final-comment-period">This week's FCPs</a> are:</p>
<ul>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2314">Rust 2018 roadmap</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2325">Stable SIMD in Rust</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2282">Cargo profile dependencies</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2333">Prior art</a>. A section to the RFC template where RFC authors may discuss the experience of other programming languages.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2330">Amend RFC 0141 Lifetime elision: Mention deduplicated lifetimes</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2226">Hexadecimal integers with fmt::Debug, including within larger types</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2151">Raw identifiers</a>. Add a raw identifier format <code>r#ident</code>, so crates written in future language epochs/versions can still use an older API that overlaps with new keywords.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2046">label-break-value</a>. Allow a break not only out of <code>loop</code>, but of labelled blocks with no loop</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2250">Finalize syntax of <code>impl Trait</code> and <code>dyn Trait</code> with multiple bounds</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2298"><code>?</code> repetition in macro rules</a>.</li>
<li>[disposition: postpone] <a href="https://github.com/rust-lang/rfcs/pull/1858">Immovable types</a>. Add built-in trait <code>Move</code> which all existing types will implement. Types which do not implement it cannot move after they have been borrowed</li>
<li>[disposition: postpone] <a href="https://github.com/rust-lang/rfcs/pull/1888">Proper tail calls</a>. Explicit proper tail calls to Rust via the <code>become</code> keyword.</li>
<li>[disposition: postpone] <a href="https://github.com/rust-lang/rfcs/pull/2185">Movable array iterators</a>.</li>
<li>[disposition: close] <a href="https://github.com/rust-lang/rfcs/pull/2020">Implement Add for OsString</a>.</li>
</ul>
<h4>New RFCs</h4>
<ul>
<li><a href="https://github.com/rust-lang/rfcs/pull/2342">Allow <code>if</code> and <code>match</code> in constants</a>.</li>
<li><a href="https://github.com/rust-lang/rfcs/pull/2341">Allow locals and destructuring in const fn</a>.</li>
<li><a href="https://github.com/rust-lang/rfcs/pull/2338">Type alias enum variants</a>.</li>
</ul>
<h3>Upcoming Events</h3>
<p>The community team is trying to improve outreach to meetup organisers. Please fill out their <a href="https://docs.google.com/forms/d/e/1FAIpQLSf52YXGhqBaHtCXtVna4iHYMK7IQaTqUW6V-ztsZC8C2TBInQ/viewform">call for contact info</a> if you are running or used to run a meetup.</p>
<ul>
<li><a href="https://internals.rust-lang.org/t/release-cycle-triage-proposal/3544">Feb 22. Rust release triage</a>.</li>
<li><a href="https://www.meetup.com/Rust-London-User-Group/events/246860921/">Feb 22. London, GB - LDN Talks: February 2018</a>.</li>
<li><a href="https://www.meetup.com/RustMN/events/247512052/">Feb 22. Minneapolis, US - February 2018 Meetup</a>.</li>
<li><a href="https://www.meetup.com/Rust-Dev-in-Mountain-View/events/glnfcpyxdbxb/">Feb 25. Mountain View, US - Open Table / Icebreaker: what projects are you working on</a>.</li>
<li><a href="https://www.meetup.com/triangle-rustaceans/events/kkjnpnyxdbjc/">Feb 26. Durham, US - Triangle Rustaceans - Rust 102 -- Choose Your Own Adventure</a>.</li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-content">Feb 27. Rust Community Content Subteam Meeting at #rust-content on irc.mozilla.org</a>.</li>
<li><a href="https://www.meetup.com/rust-language-milano/events/247930375/">Feb 28. Milano, IT - Rust Language Milano - Da Rust a Firefox Quantum passando da Servo</a>.</li>
<li><a href="https://www.meetup.com/Rust-Boulder-Denver/events/247751967/">Feb 28. Denver, US - denver.rs reactivate!()</a>.</li>
<li><a href="https://bitfury.timepad.ru/event/665119/">Feb 28. Moscow, RU - Rust Meetup from Exonum &amp; Parity developers</a>.</li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-community">Feb 28. Rust Community Team Meeting at #rust-community on irc.mozilla.org</a>.</li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-docs">Feb 28. Rust Documentation Team Meeting at #rust-docs on irc.mozilla.org</a>.</li>
<li><a href="https://t.me/joinchat/EkKINhHCgZ9llzvPidOssA">Feb 28. Rust Events Team Meeting</a>.</li>
<li><a href="https://www.meetup.com/Rust-Dev-in-Mountain-View/events/glnfcpyxfbgb/">Mar 4. Mountain View, US - Open Table / Icebreaker: what projects are you working on</a>.</li>
<li><a href="https://www.meetup.com/Rust-London-User-Group/events/247286584/">Mar 5. London, GB - Rust learning and hacking evening #8</a>.</li>
<li><a href="https://www.meetup.com/Johannesburg-Rust-Meetup/events/cpblrnyxfbjb/">Mar 6. Johannesburg, SA - Monthly Meetup of the Johannesburg Rustaceans</a>.</li>
<li><a href="https://www.meetup.com/opentechschool-berlin/events/krnczlyxfbkb/">Mar 7. Berlin, DE - OpenTechSchool Berlin - Rust Hack and Learn</a>.</li>
<li><a href="https://www.meetup.com/Rust-ATL/events/rhvgrmyxfbkb/">Mar 7. Atlanta, US - Grab a beer with fellow Rustaceans</a>.</li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-community">Mar 7. Rust Community Team Meeting at #rust-community on irc.mozilla.org</a>.</li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-docs">Mar 7. Rust Documentation Team Meeting at #rust-docs on irc.mozilla.org</a>.</li>
<li><a href="https://internals.rust-lang.org/t/release-cycle-triage-proposal/3544">Mar 8. Rust release triage</a>.</li>
<li><a href="https://www.meetup.com/columbus-rs/events/czcwhlyxfblb/">Mar 8. Columbus, US - Columbus Rust Society - Monthly Meeting</a>.</li>
</ul>
<p>If you are running a Rust event please add it to the <a href="https://www.google.com/calendar/embed?src=apd9vmbc22egenmtu5l6c5jbfc%40group.calendar.google.com">calendar</a> to get
it mentioned here. Email the <a href="mailto:community-team@rust-lang.org">Rust Community Team</a> for access.</p>
<h3>Rust Jobs</h3>
<ul>
<li><a href="https://www.facebook.com/careers/jobs/a0I1H00000LCTYYUA5/.">Software Engineer at Facebook</a></li>
</ul>
<p><em>Tweet us at <a href="https://twitter.com/ThisWeekInRust">@ThisWeekInRust</a> to get your job offers listed here!</em></p>
<h3>Quote of the Week</h3>
<p><em>No quote was selected for QotW.</em></p>
<p><a href="http://users.rust-lang.org/t/twir-quote-of-the-week/328">Submit your quotes for next week</a>!</p>
<p><em>This Week in Rust is edited by: <a href="https://github.com/nasa42">nasa42</a> and <a href="https://github.com/llogiq">llogiq</a>.</em></p>Tue, 20 Feb 2018 05:00:00 +0000TWiR ContributorsDaniel Pocock: SwissPost putting another nail in the coffin of Swiss sovereignty358 at https://danielpocock.comhttps://danielpocock.com/swisspost-swissid-another-nail-in-the-coffin-sovereignty
<div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>A few people have recently asked me about the <em>SwissID</em>, as SwissPost has just been sending spam emails out to people telling them "Link your Swiss Post user account to SwissID".</p>
<p>This coercive new application of technology <a href="https://www.swissid.ch/en/faq">demands users email addresses and mobile phone numbers</a> "for security". A web site coercing people to use text messages "for security" has quickly become a red flag for most people and many blogs have already covered <a href="https://danielpocock.com/how-many-mobile-phone-accounts-will-be-hijacked-this-summer">why it is only an illusion of security, putting your phone account at risk so companies can profit from another vector for snooping on you</a>.</p>
<p><em>SwissID</em> is not the only digital identity solution in Switzerland but as it is run by SwissPost and has a name similar to another service it is becoming very well known.</p>
<p>In 2010 they began offering a solution which they call <em>SuisseID</em> (notice the difference? They are pronounced the same way.) based on <a href="https://postsuisseid.ch/en/questions/faq/258-is-suisseid-also-available-to-download-as-a-software-certificate">digital certificates and compliant with Swiss legislation</a>. Public discussion <a href="https://www.srf.ch/sendungen/kassensturz-espresso/themen/geld/suisseid-mehr-als-ein-teurer-flop">focussed on the obscene cost</a> with little comment about the privacy consequences and what this means for Switzerland as a nation.</p>
<p>Digital certificates often embed an email address in the certificate.</p>
<p>With <em>SwissID</em>, however, they have a web site that looks like <a href="https://www.swissid.ch/">little more than vaporware</a>, giving no details at all whether certificates are used. It appears they are basically <a href="https://danielpocock.com/sites/danielpocock.com/files/170516_swisssign_factsheet_B2B_en.pdf">promoting an app</a> that is designed to harvest the email addresses and phone numbers of any Swiss people who install it, lulling them into that folly by using a name that looks like their original <em>SuisseID</em>. <em>If it looks like <a href="https://en.wikipedia.org/wiki/Phishing">phishing</a>, if it feels like <a href="https://en.wikipedia.org/wiki/Phishing">phishing</a> and if it smells like <a href="https://en.wikipedia.org/wiki/Phishing">phishing</a> to any expert takes a brief sniff of their FAQ, then what else is it?</em></p>
<p>The thing is, the original <em>SuisseID</em> runs on a standalone smartcard so it doesn't need to have your mobile phone number, <a href="https://play.google.com/store/apps/details?id=com.nth.swisspost&amp;hl=en">have permissions to all the data in your phone</a> and be limited to working in areas with mobile phone signal.</p>
<p>The emails currently being sent by SwissPost tell people they must "Please use a private e-mail address for this purpose" but they don't give any information about the privacy consequences of creating such an account or what their app will do when it has access to read all the messages and contacts in your phone.</p>
<h3>The actions you can take that they didn't tell you about</h3>
<ul><li>You can post a registered letter to SwissPost and tell them that for privacy reasons, you are immediately retracting the email addresses and mobile phone numbers they currently hold on file and that you are exercising your right not to give an email address or mobile phone number to them in future.</li>
<li>If you do decide you want a <em>SwissID</em>, create a unique email address for it and only use that email address with SwissPost so that it can't be cross-referenced with other companies. This email address is also like a <a href="https://en.wikipedia.org/wiki/Sentinel_species">canary in a coal mine</a>: if you start receiving spam on that email address then you know SwissPost/<em>SwissID</em> may have been hacked or the data has been leaked or sold.</li>
<li>Don't install their app and if you did, remove it and you may want to change your mobile phone number.</li>
</ul><p><img src="https://danielpocock.com/sites/danielpocock.com/files/canary2.jpg" /></p>
<p>Oddly enough, none of these privacy-protecting ideas were suggested in the email from SwissPost. Who's side are they on?</p>
<h3>Why should people be concerned?</h3>
<p>SwissPost, like every postal agency, has seen traditional revenues drop and so they seek to <a href="https://www.postfinance.ch/en/about-us/media/newsroom/press-releases/q3-2017-swiss-post-achieves-good-result-in-difficult-environment.html">generate more revenue from direct marketing</a> and they are constantly looking for ways to extract and profit from data about the public. They are also a huge company with many employees: when dealing with vast amounts of data in any computer system, it only takes one employee to compromise everything: just think of how <a href="https://en.wikipedia.org/wiki/Edward_Snowden">Edward Snowden</a> was able to act alone to extract many of the NSA's most valuable secrets.</p>
<p>SwissPost is going to great lengths to get accurate data on every citizen and resident in Switzerland, including deploying an app to get your mobile phone number and demanding an email address when you use their web site. That also allows them to cross-reference with your IP addresses.</p>
<ul><li>Any person or organization who has your email address or mobile number may find it easier to get your home address.</li>
<li>Any person or organization who has your home address may be able to get your email address or mobile phone number.</li>
<li>When you call a company from your mobile phone and their system recognizes your phone number, it becomes easier for them to match it to your home address.</li>
<li>If SwissPost and the SBB successfully convince a lot of people to use a <em>SwissID</em>, some other large web sites may refuse to allow access without getting you to link them to your <em>SwissID</em> and all the data behind it too. Think of how many websites already try to coerce you to give them your mobile phone number and birthday to "secure" your account, but worse.</li>
</ul><p><a href="https://danielpocock.com/sites/danielpocock.com/files/170516_swisssign_factsheet_B2B_en.pdf"><img src="https://danielpocock.com/sites/danielpocock.com/files/swissid-cia.png" /></a></p>
<h3>The Google factor</h3>
<p>The creepiest thing is that over seventy percent of people are apparently using Gmail addresses in Switzerland and these will be a dependency of their registration for <em>SwissID</em>.</p>
<p>Given that <em>SwissID</em> is being promoted as a solution compliant with <a href="https://en.wikipedia.org/wiki/ZertES">ZertES legislation</a> that can act as an interface between citizens and the state, the intersection with such a powerful foreign actor as Gmail is extraordinary. For example, if people are registering to vote in Switzerland's renowned <a href="https://en.wikipedia.org/wiki/Popular_initiative_(Switzerland)#Federal_popular_initiative">referendums</a> and their communication is under the surveillance of a foreign power like the US, that is a mockery of democracy and it makes the allegations of Russian election hacking look like child's play.</p>
<p>Switzerland's referendums, decentralized system of Government, part-time army and privacy regime are all features that maintain a balance between citizen and state: by centralizing power in the hands of <em>SwissID</em> and foreign IT companies, doesn't it appear that the very name <em>SwissID</em> is a mockery of the Swiss identity?</p>
<p><a href="http://yellow-in-motion.swisspost.ch/"><img alt="Yellow in motion" src="https://danielpocock.com/sites/danielpocock.com/files/dead_canaries.jpg" /></a></p>
<p><em>No canaries were harmed in the production of this blog.</em></p>
</div></div></div>Sun, 18 Feb 2018 22:17:00 +0000Daniel.PocockDon Marti: The tracker will always get through?https://blog.zgp.org/the-tracker-will-always-get-through/https://blog.zgp.org/the-tracker-will-always-get-through/
<p><em>(I work for Mozilla. None of this is secret. None of this is Mozilla policy. Not speaking for Mozilla here.)</em></p>
<p>A big objection to tracking protection is the idea
that the tracker will always get through. Some people
suggest that as browsers give users more ability to
control how their personal information gets leaked
across sites, things won't get better for users,
because third-party tracking will just keep up.
On this view, today's easy-to-block third-party
cookies will be replaced by techniques such as passive
fingerprinting where it's hard to tell if the browser
is succeeding at protecting the user or not, and
users will be stuck in the same place they are now,
or worse.</p>
<p>I doubt this is the case because we're playing a
more complex game than just trackers vs. users.
The game has at least five sides, and some of the
fastest-moving players with the best understanding of
the game are the adfraud hackers. Right now adfraud
is losing in some areas where they had been winning,
and the resulting shift in adfraud is likely to shift
the risks and rewards of tracking techniques.</p>
<h3>Data center adfraud</h3>
<p>Fraudbots, running in data centers, visit legit sites
(with third-party ads and trackers) to pick up a
realistic set of third-party cookies to make them look
like high-value users. Then the bots visit dedicated
fraudulent "cash out" sites (whose operators have the same
third-party ads and trackers) to generate valuable ad
impressions for those sites. If you wonder why so
many sites made a big deal out of "pivot to video"
but can't remember watching a video ad, this is
why. Fraudbots are patient enough to get profiled as,
say, a car buyer, and watch those big-money ads. And
the money is good enough to motivate fraud hackers to
make good bots, usually based on real browser code.
When a fraudbot network gets caught and blocked from
high-value ads, it gets recycled for lower and lower
value forms of advertising. By the time you see
traffic for sale on fraud boards, those bots are
probably only getting past just enough third-party
anti-fraud services to be worth running.</p>
<p>This version of adfraud has minimal impact on
real users. Real users don't go to fraud sites,
and fraudbots do their thing in data centers <span class="aside">Doesn't everyone do their Christmas
shopping while chilling out in the cold aisle at an
Amazon AWS data center? Seems legit to me.</span>
and don't touch users' systems. The companies that
pay for it are legit publishers, who not only have
to serve pages to fraudbots—remember, a bot
needs to visit enough legit sites to look like a real
user—but also end up competing with adfraud for
ad revenue. Adfraud has only really been a problem
for legit publishers. The adtech business is fine
with it, since they make more money from fraud than
the fraud hackers do, and the advertisers are fine
with it because fraud is priced in, so they pay the
fraud-adjusted price even for real impressions.</p>
<h3>What's new for adfraud</h3>
<p>So what's changing? More fraudbots in data centers
are getting caught, just because the adtech firms
have mostly been shamed into filtering out the
embarassingly obvious traffic from IP addresses
that everyone can tell probably don't have a
human user on them. So where is fraud going now?
More fraud is likely to move to a place where a
bot can look more realistic but probably not stay
up as long—your computer or mobile device.
Expect adfraud concealed within web pages, as a
payload for malware, and of course in lots and lots
of cheesy native mobile apps.<span class="aside">The
Google Play Store has an ongoing problem with adfraud,
which is <a href="https://blog.checkpoint.com/2018/01/12/childrens-apps-google-play-display-porn-ads/">content marketing gold for Check Point
Software</a>,
if you like "shitty app did WHAT?" stories.</span>
Adfraud makes way more money than cryptocurrency
mining, using less CPU and battery.</p>
<p>So the bad news is that you're going to have
to reformat your uncle's computer a lot this
year, because more client-side fraud is coming.
Data center IPs don't get by the ad networks as well
as they once did, so adfraud is getting personal.
The good news, is, hey, you know all that big, scary
passive fingerprinting that's supposed to become the
harder-to-beat replacement for the third-party cookie?
Client-side fraud has to beat it in order to get paid,
so they'll beat it. As a bonus, client-side bots are
way better at attribution fraud (where a fraudulent
ad gets credit for a real sale) than data center bots.</p>
<p>Users don't have to get protected from
every possible tracking technique in
order to <a href="https://blog.zgp.org/want-to-lose-a-hacking-contest-or-win-a-reputation-contest/">shift the web advertising
game from a hacking contest to a reputation
contest</a>.
It often helps simply to shift the advertiser's ROI
from negative-externality advertising below the ROI
of positive-externality advertising.<br />Advertisers have two possible responses to adfraud:
either try to out-hack it, or join the "flight to
quality" and cut back on trying to follow big-money
users to low-reputation sites in the first place.
Hard-to-detect client-side bots, by making creepy
fingerprinting techniques less trustworthy, tend to
increase the uncertainty of the hacking option and
make flight to quality relatively more attractive.</p>Sun, 18 Feb 2018 08:00:00 +0000Chris Cooper: Experiments in productivity: the shared bug queuehttp://coopcoopbware.tumblr.com/post/170952242320http://coopcoopbware.tumblr.com/post/170952242320
<h3>Maybe you have this problem too</h3>
<p>You manage or are part of a team that is responsible for a certain functional area of code. Everyone on the team is at different points in there career. Some people have only been there a few years, or maybe even only a few months, but they’re hungry and eager to learn. Other team members have been around forever, and due to that longevity, they are go-to resources for the rest of your organization when someone needs help in that functional area. More-senior people get buried under a mountain of review requests, while those less-senior engineers who are eager to help and grow their reputation get table scraps.</p>
<p>This is the situation I walked into with the <a href="http://coopcoopbware.tumblr.com/post/167553827650/introducing-the-developer-workflow-team" target="_blank">Developer Workflow</a> team.</p>
<p>This was the first time that <a href="https://www.mozilla.org/" target="_blank">Mozilla</a> had organized a majority (4) of build module peers in one group. There are still isolated build peers in other groups still, but we’ll get to that in a bit.</p>
<p>With apologies to Ted, he’s the elder statesman of the group, having once been the build module owner himself before handing that responsiblity off to Greg (gps), the current module owner. Ted has been around Mozilla for so long that he is a go-to resource for not only build system work but many other projects, e.g. crash analysis, he’s been involved with. In his position as module owner, Greg bears the brunt of the current review workload for the build system. He needs to weigh-in on architectural decisions, but also receives a substantial number of drive-by requests simply because he is the module owner.</p>
<p>Chris Manchester and Mike Shal by contrast are relatively new build peers and would frequently end up reviewing patches for each other, but not a lot else. How could we more equitably share the review load between the team without creating more work for those engineers who were already oversubscribed?</p>
<h3>Enter the shared bug queue</h3>
<p>When I first came up with this idea, I thought that certainly this must have been tried at some point in the history of Mozilla. I was hoping to plug into an existing model in bugzilla, but alas, such a thing did not already exist. It took a few months of back-and-forth with our reisdent Bugmaster at Mozilla, <a href="https://emmah.net/index.html" target="_blank">Emma</a>, to get something setup, but by early October, we had a shared queue in place.</p>
<h3>How does it work?</h3>
<p></p><figure class="alignright"><a href="http://knowyourmeme.com/memes/miracles-fucking-magnets-how-do-they-work" target="_blank"><img alt="ICP" src="http://i0.kym-cdn.com/entries/icons/mobile/000/002/395/magnets_c.jpg" /></a></figure><p></p>
<p>We created a fictitious meta-user, core-build-config-reviews@mozilla.bugs. Now whenever someone submits a patch to the Core::Build Config module in bugzilla, the suggested reviewer always defaults to that shared user. Everyone on the teams watches that user and pulls reviews from “their” queue.</p>
<p>That’s it. No, really.</p>
<p>Well, okay, there’s a little bit more process around it than that. One of the dangers of a shared queue is that since no specific person is being nagged for pending reviews, the queue could become a place where patches go to die. As with any defect tracking system, regular triage is critically important.</p>
<h3>Is it working?</h3>
<p>In short: yes, very much so.</p>
<p>Subjectively, it feels great. We’ve solved some tricky people problems with a pretty straightforward technical/process solution and that’s amazing. From talking to all the build peers, they feel a new collective sense of ownership of the build module and the code passing through it. The more-senior people feel they have more time to concentrate on higher level issues or deeper reviews. The less-senior people are building their reputations, both among the build peers and outside the group to review requesters.</p>
<p>Numerically speaking, the absolute number of review requests for the Core::Build Config module is consistent since the adoption of the shared queue. The distribution of actual reviewers has changed a lot though. Greg and Ted still end up reviewing their share of escalated requests — it’s still possible to assign reviews to specific people in this system — but Mike Shal and Chris have increased their review volume substantially. What’s even more awesome is that the build peers who are *NOT* in the Developer Workflow team are also fully onboard, regularly pulling reviews off the shared queue. Kudos to Nick Alexander, Nathan Froyd, Ralph Giles, and Mike Hommey for also embracing this new system wholeheartedly.</p>
<p>The need for regular triage has also provided another area of growth for the less-senior build peers. Mike Shal and Chris Manchester have done a great job of keeping that queue empty and forcing the team to triage any backlog each week in our team meeting.</p>
<h3>Teh Future</h3>
<p>When we were about to set this up in October, I almost pulled the plug.</p>
<p>Over the next six months, <a href="https://wiki.mozilla.org/Phabricator" target="_blank">Mozilla is planning to switch code review tools from mozreview/splinter to phabricator</a>. <a href="https://www.phacility.com/phabricator/" target="_blank">Phabricator</a> has more modern built-in tools like <a href="https://secure.phabricator.com/book/phabricator/article/herald/" target="_blank">Herald</a> that would have made setting up this shared queue a little easier, and that’s why I paused…briefly</p>
<p>Phabricator will undoubtedly enable a host of quality-of-life improvements for developers when it is deployed, but I’m glad we didn’t wait for the new system. Mozilla engineers are already getting accustomed to the new workflow and we’re reaping the benefits <em>*right now*</em>.</p>Fri, 16 Feb 2018 20:42:49 +0000David Humphrey: Edge Cases5a89bb7e60da2f0659f4a73bhttps://blog.humphd.org/edge-cases/
<div class="kg-card-markdown"><p>Yesterday I was looking at a bug with some students. It related to a problem in a file search feature: a user found that having a folder-name surrounded with braces (e.g., <code>{name}</code>) meant that no search results were ever reported within the folder. <em>"This isn't a bug,"</em> one of them told me, <em>"because no one would ever do this."</em> I found this fascinating on a number of levels, not least because <em>someone</em> had in fact done it, and even gone so far as to file the bug.</p>
<p>I love edge cases. I'm pretty sure it started during the years I worked on <a href="http://processingjs.org/">Processing.js</a>--anyone who has worked in projects with comprehensive test suites probably knows what I mean. With that project we had a massive set of existing Java-based Processing code that we needed to make work on the web. Anything that was possible in the Java implementation needed to work 1:1 in our JavaScript version. It was amazing the spectacular variety and extremes we'd see in how people wrote their code. Every time we'd ship something, a user would show up and <a href="http://blog.humphd.org/vocamus-1335/">tell us about some edge case we'd never seen before</a>. We'd fix it, add tests, and repeat the cycle.</p>
<p>Doing this work over many years, I came to understand that growth happens at a project's edge rather than in the middle: the code we <em>wanted</em> to work on (some pet optimization or refactor) was rarely where we <em>needed</em> to be doing. Rather, the most productive space we could occupy was at the unexplored edges of our territory. And to do this, to really know what was "out there," we needed help; there was too much we couldn't see, we needed people to stumble across the uncultivated border and tell us what needed attention.</p>
<p>The thing about an edge case bug is that its seemingly trivial nature often points to something more fundamental: a total lack of attention to something deep in your system. The assumptions underpinning your entire approach, the ones you don't even know that you've made, suddenly snap into sharp focus and you're forced to face them for the first time. Even well designed programs can't avoid this: whatever you optimize for, whatever cases you design and test against, you necessarily have to leave things out in order to ship something. At which point reports of edge case bugs become an incredible tool in the fight to open your territory beyond its current borders.</p>
<p>It's easy to think that what I'm describing only applies to small or inexperienced teams. <em>"Surely if you just engineered things properly from the start, you could avoid this mess."</em> Yet big, well-funded, engineering powerhouses struggle just the same. Take Apple, for example. This week they've had to deal with yet another <a href="https://www.theverge.com/2018/2/15/17015654/apple-iphone-crash-ios-11-bug-imessage">show-stopper bug in iOS</a>--if you paste a few characters of text into your phone it crashes. There's a <a href="https://manishearth.github.io/blog/2018/02/15/picking-apart-the-crashing-ios-string/">great write-up about the bug</a> by <a href="https://twitter.com/manishearth">@manishearth</a>:</p>
<blockquote>
<p>Basically, if you put this string in any system text box (and other places), it crashes that process...The original sequence is U+0C1C U+0C4D U+0C1E U+200C U+0C3E, which is a sequence of Telugu characters: the consonant ja (జ), a virama ( ్ ), the consonant nya (ఞ), a zero-width non-joiner, and the vowel aa ( ా)...then I saw that there was a sequence in Bengali that also crashed. The sequence is U+09B8 U+09CD U+09B0 U+200C U+09C1, which is the consonant “so” (স), a virama ( ্ ), the consonant “ro” (র), a ZWNJ, and vowel u ( ু).</p>
</blockquote>
<p>Want to know which languages Apple's iOS engineers <strong>aren't</strong> using on a daily basis or in their tests? It's easy to point a knowing finger and say that they should know better, but I wonder how well tested your code is in similar situations? You can't believe how many bugs I find with students in my class, whose usernames and filepaths contain Chinese or other non-English characters, and software which blows up because it was only ever tested on the ASCII character set.</p>
<p>The world is big place, and we should all be humbled by its diversity of people and places. The software we build to model and interact with it will always be insufficient to the needs of real people. <em>"Everyone does this..."</em> and <em>"No one would ever do that..."</em> are naive statements you only make until you've seen just how terrible all code is at the edges. After you've been burned a few times, after you've been humbled and learned to embrace your own finite understanding of the world, you come to love reports of edge cases, and the opportunity they provide to grow, learn, and connect with someone new.</p>
</div>Fri, 16 Feb 2018 16:12:24 +0000David HumphreyGervase Markham: Going Homehttps://blog.gerv.net/?p=3972http://feedproxy.google.com/~r/HackingForChrist/~3/JwnKllb6CB4/
<p>I’m going home.</p>
<p>As some of my readers will know, my <a href="https://www.gerv.net/cancer/">cancer</a> (read that link if the fact I have cancer is new to you) has been causing difficulty in my liver this year, and recently we had a meeting with my consultant to plot a way forward. He said that recent scans had shown an increased growth rate of some tumours (including the liver one), and that has overwhelmed my body’s ability to cope with the changes cancer brings. The last two months have seen various new symptoms and a reasonably rapid decline in my general health. The next two months will be more of the same unless something is done.</p>
<p>After some unsuccessful procedures on my liver over the course of this year, the last option is radiotherapy to try and shrink the problem tumour; we are investigating that this week. But even if that succeeds, the improvement will be relatively short-lived – perhaps 3-6 months – as the regrowth rate will be faster. If radiotherapy is not feasible or doesn’t work, the timelines are rather shorter than that. My death is not imminent, but either way I am unlikely to see out 2018. In all this, my wife, my children and I are confident that God is in charge and his purposes are good, and we can trust him and not be afraid of what is coming. We don’t know what the future holds for each of us, but he does.</p>
<p>We’ve taken this news as a sign to make some significant changes. The most relevant to readers of this blog is that <b>I am stepping away from Mozilla</b> so I can spend more time focussed on the most important things – my relationships with Jesus, and with my family. I love my work, and God has blessed my time at Mozilla and enabled me to do much which I think have been good for the Internet and the world. However, there are things in life which are much more important, and it’s now time for others to take up those projects and causes and carry them into the future. I have every confidence in my colleagues and fellow Mozillians that this will be done with the greatest care and skill. The <a href="http://wiki.mozilla.org/CA">CA program</a>, <a href="http://mozilla.org/moss">MOSS</a>, and <a href="https://blog.mozilla.org/netpolicy/">Mozilla’s policy work</a> are all in very good hands.</p>
<p>If you pray, please pray that we would make wise decisions about what to do when, and that we would live through this process in a way that brings glory to Jesus.</p>
<p>In case it’s of interest, we have set up a <a href="https://groups.google.com/forum/#!forum/lightandmomentary">read-only mailing list</a> which people can join to keep informed about what is going on, and to hear a bit about how we are handling this and what we would like prayer for. You can subscribe to the list using that link, if you have a Google account. If you don’t you can still join by emailing <a href="mailto:lightandmomentary+subscribe@googlegroups.com">lightandmomentary+subscribe@googlegroups.com</a>.</p>
<blockquote><p>
“Though outwardly we are wasting away, yet inwardly we are being renewed day by day. For our <b>light and momentary</b> troubles are achieving for us an eternal glory that far outweighs them all. So we fix our eyes not on what is seen, but on what is unseen, since what is seen is temporary, but what is unseen is eternal.” — 2 Cor 4:16-18.
</p></blockquote>
<p>If I have done anything good in 18 years at Mozilla, may God get all the glory.</p>
<img alt="" height="1" src="http://feeds.feedburner.com/~r/HackingForChrist/~4/JwnKllb6CB4" width="1" />Fri, 16 Feb 2018 16:00:38 +0000gervDaniel Stenberg: Why is your email in my car?https://daniel.haxx.se/blog/?p=10856https://daniel.haxx.se/blog/2018/02/16/why-is-your-email-in-my-car/
<p>I got this email in German…</p>
<blockquote>
<pre>Subject: Warumfrage
Schönen guten Tag
Ich habe auf meinem Navi aus meinem Auto einen Riesentext wo unter anderem Ihre Mailadresse zu sehen ist?
Können Sie mich schlau machen was es damit auf sich hat ?</pre>
</blockquote>
<p>… which translated into English says:</p>
<blockquote><p><span class="" id="result_box" lang="en"><span class="">I have a huge text on my sat nav in my car where, among other things,</span> y<span class="">our email address can be seen?</span></span></p>
<p><span class="">Can you tell me what this is all about?</span></p></blockquote>
<p>I replied (in English) to the question, explained how I’m the main author of <a href="https://curl.haxx.se/">curl</a> and how his navigation system is probably using this. I then asked what product or car he saw my email in and if he could send me a picture of my email being there.</p>
<p>He responded quickly and his very brief answer only says it is a Toyota Verso from 2015. So I put an image of such a car on the top of this post.</p>Fri, 16 Feb 2018 13:07:37 +0000Daniel StenbergK Lars Lohn: Lars and the Real Internet of Things, Part 3tag:blogger.com,1999:blog-12340845.post-3281710349241420487http://www.twobraids.com/2018/02/lars-and-real-internet-of-things-part-3.html
In <a href="http://www.twobraids.com/2018/02/lars-and-real-internet-of-things-part-2.html">Part 2 of this series</a>, I demonstrated loading and running the <a href="https://iot.mozilla.org/">Things Gateway by Mozilla</a> software onto a Raspberry Pi. I showed how to use a DIGI XStick, which implements the Zigbee protocol, to run a light bulb and smart plug.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-XtU787pfQEo/WoYtG9UrreI/AAAAAAAApQQ/p1xTNpQZCA8HY-vtG_EINS9wlwJUs98tACLcBGAs/s1600/2018-02-15%2B16.39.26.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="320" src="https://3.bp.blogspot.com/-XtU787pfQEo/WoYtG9UrreI/AAAAAAAApQQ/p1xTNpQZCA8HY-vtG_EINS9wlwJUs98tACLcBGAs/s320/2018-02-15%2B16.39.26.jpg" width="240" /></a></div>Today, I'm going to take that system and make it work with the Z-Wave protocol, too. Then I'll demonstrate how to use a rule to make a Z-Wave switch follow the same state as a Zigbee switch.<br /><br /><i><b>Goal</b>: add an Aoetec Z-Stick to the existing project, pair it with some Z-Wave devices, and, finally, demonstrate a rule that crosses over the barrier between the two protocols. This addition to the project will maintain total local control so there should be no communication outside to the Internet.</i><br /><br /><br /><br /><br /><br /><br /><br /><div class="separator" style="clear: both; text-align: center;"><b>Requirements &amp; Parts List</b>:<br /></div><br /><table border="1" style="margin-left: 0px; margin-right: auto; text-align: left;"><tbody><tr><th>Item</th><th>What's it for?</th><th>Where I got it</th></tr><tr><td>The Raspberry Pi and associated hardware from Part 2 of this series.</td><td>this is the base platform that we'll be adding onto</td><td>from <a href="http://www.twobraids.com/2018/02/lars-and-real-internet-of-things-part-2.html">Part 2 of this series</a></td></tr><tr><td>Aeotec Z-Stick</td><td>an adapter that enables the Things Gateway to talk Z-Wave</td><td>Amazon</td></tr><tr><td>Aeotec Smart Switch 6 ZW096-A02</td><td>a Z-Wave switch to control</td><td>Amazon</td></tr><tr><td>GE ZW1403 Smart Switch</td><td>a Z-Wave switch to control (this device has been temperamental &amp; may not be the best choice)</td><td>Amazon</td></tr></tbody></table><br /><br />This part of the project is going to be ridiculously easy. We're starting with the system as it stood at the end of the last posting: a Things Gateway on an Raspberry Pi that only understands Zigbee devices.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-i4knhAcDUTE/WoYtoT2bvXI/AAAAAAAApQY/HDiJU3RHKEABiw688lcE3zfGZoMUiZUfwCLcBGAs/s1600/2018-02-15%2B16.34.11.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="320" src="https://3.bp.blogspot.com/-i4knhAcDUTE/WoYtoT2bvXI/AAAAAAAApQY/HDiJU3RHKEABiw688lcE3zfGZoMUiZUfwCLcBGAs/s320/2018-02-15%2B16.34.11.jpg" width="240" /></a></div>To start, I unplugged the Raspberry Pi from its power supply. I plugged the Aoetec Z-Stick into a USB port on the Raspberry Pi - recognizing that the existing DIGI XStick had to be repositioned for both to fit. I then reapplied power to the Raspberry Pi and it booted. I assembled all the lights for this experiment.<br /><br />From left to right: a grocery store LED bulb on the Z-Wave Aeotec Smart Switch 6 to be called AEO 007; an LED bulb disguised as a old fashioned filament bulb on the Zigbee Sylvania Smart Plug to be called SYLV 002; a Zigbee CREE dimmable bulb to be called CREE 006; a bulk Costco compact fluorescent from 2013 on a bulky and sideways Z-Wave GE Smart Switch to be called GE 001.<br /><br />The Aoetec Z-Stick is a feature packed USB device that implements the Z-Wave+ protocol. My first advice, though, is to not read the instructions. You see, the Things Gateway support for Z-Wave is still in infancy and doesn't particularly fit well into the pairing methods traditionally used by Z-Wave devices. <br /><br />The Z-Stick instructions will tell you to pair Z-Wave devices in a manner that the Things Gateway does not yet understand. I suggest that you hold off and pair Z-Wave devices only through the Things Gateway software. This will save you a lot of pain.<br /><br />I went back to my browser and entered "gateway.local" in the URL bar. I had to login using the credentials that I provided during the previous setup. That lead me to this screen:<br /><div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-4rCLkI0Hxlo/WoYSYTieLxI/AAAAAAAApOw/Se4D12kpYCoZAYcnqjW-7eh93o3MpWUIQCLcBGAs/s1600/03-001.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://3.bp.blogspot.com/-4rCLkI0Hxlo/WoYSYTieLxI/AAAAAAAApOw/Se4D12kpYCoZAYcnqjW-7eh93o3MpWUIQCLcBGAs/s320/03-001.jpg" width="216" /></a></div>I pressed the "+" button to start pairing the two new Z-Wave devices. The GE device behaves differently than the Aeotec device. Normally when pairing Z-Wave things, one must press a button on the device to be added to the system. However the GE device comes from the factory ready to go without having this button pressed. It shows up on the screen, but the Aeotec device does not.<br /><div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-mNkVnH2ZUc8/WoYTIrEkHHI/AAAAAAAApO4/DTx3C2Zj4y42I_RMA_uVl3uSxF09FFkWwCLcBGAs/s1600/03-002.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://2.bp.blogspot.com/-mNkVnH2ZUc8/WoYTIrEkHHI/AAAAAAAApO4/DTx3C2Zj4y42I_RMA_uVl3uSxF09FFkWwCLcBGAs/s320/03-002.jpg" width="216" /></a></div>To to keep track of the devices, I renamed this first Z-Wave device as "GE 001" and pressed the "Save" button.<br /><div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-S4LjDTW-4yw/WoYTIjMM85I/AAAAAAAApO8/8qtCkLXLt2QNpGasM69GHxao2a9X34r5QCEwYBhgL/s1600/03-003.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://2.bp.blogspot.com/-S4LjDTW-4yw/WoYTIjMM85I/AAAAAAAApO8/8qtCkLXLt2QNpGasM69GHxao2a9X34r5QCEwYBhgL/s320/03-003.jpg" width="216" /></a></div>Now I had to get the Aeotec device added. I found out the hard way that the little spinner next to "Scanning for new devices..." must still be spinning. In an earlier trial for this demo, I had to press "Done" and then immediately press the "+" button to return to this screen.<br /><br />The Aeotec Smart Plug uses a more traditional Z-Wave approach to pairing. I pressed the circular indent on the corner of the plug itself. Since I had a light plugged into the Smart Plug, it illuminated. After a few moments, the Smart Plug appeared on the page. If it doesn't appear for you, wait for the colored lights on the edge of the plug to calm down, and press the button again.<br /><br />I renamed the plug to a more understandable name before pressing "Save" and "Done".<br /><div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-zJ5S75mrsQ8/WoYTI63bCvI/AAAAAAAApPQ/Wr_izlikCe8VsGRewcyi052n2QWe1fghwCEwYBhgL/s1600/03-004.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://2.bp.blogspot.com/-zJ5S75mrsQ8/WoYTI63bCvI/AAAAAAAApPQ/Wr_izlikCe8VsGRewcyi052n2QWe1fghwCEwYBhgL/s320/03-004.jpg" width="216" /></a></div>This gives me four devices connected to my Things Gateway: two that speak Zigbee and two that speak Z-Wave. I played around with the controls, turning each on and off in turn. I also made the discovery that support for the Sylvania Smart Plug was not as complete as I thought, as it was not registering anything but on or off.<br /><div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-BH8jK_XtDCg/WoYTJJUm_LI/AAAAAAAApPM/-8fkuTNQhy4Z74-det5Sqqtx6fv4lEedACEwYBhgL/s1600/03-005.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-BH8jK_XtDCg/WoYTJJUm_LI/AAAAAAAApPM/-8fkuTNQhy4Z74-det5Sqqtx6fv4lEedACEwYBhgL/s320/03-005.jpg" width="216" /></a></div>Now the fun begins, I can cross the boundary between Z-Wave and Zigbee and make these devices work together using rules.<br /><br />Let's make the compact fluorescent in the Z-Wave GE 001 plug follow whatever state the old fashioned bulb (actually it's LED) in the Zigbee SYLV 002 plug.<br /><br />I clicked the Menu button and selected Rules<br /><div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-jvBZm_t4EBk/WoYXMmQwfjI/AAAAAAAApPU/MKwGDilQ_tYvPZOGV4MlaQAiN60bnyLJwCLcBGAs/s1600/03-006.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-jvBZm_t4EBk/WoYXMmQwfjI/AAAAAAAApPU/MKwGDilQ_tYvPZOGV4MlaQAiN60bnyLJwCLcBGAs/s320/03-006.jpg" width="216" /></a></div>I dragged the SYLV 002 device up into the "device as input" section and then used the drop down box to select the "On" property.<br /><div class="separator" style="clear: both; text-align: center;"> <a href="https://4.bp.blogspot.com/-kLsPsMzPg-k/WoYeHrvMtHI/AAAAAAAApP8/dmN2C5ejhKwfI0s5dAgKqfvwJ5FevkNtwCLcBGAs/s1600/03-007.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-kLsPsMzPg-k/WoYeHrvMtHI/AAAAAAAApP8/dmN2C5ejhKwfI0s5dAgKqfvwJ5FevkNtwCLcBGAs/s320/03-007.jpg" width="216" /></a></div>Then I dragged the GE 001 device up to the "device as output" section and selected the "On" property. Then went to the top of the box and named the rule: <br /><div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/--7wGkzehoAA/WoYeHYxpVQI/AAAAAAAApP4/79_d3unXOakhKWw_lFGsI2v6OkocjjGOgCEwYBhgL/s1600/03-008.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/--7wGkzehoAA/WoYeHYxpVQI/AAAAAAAApP4/79_d3unXOakhKWw_lFGsI2v6OkocjjGOgCEwYBhgL/s320/03-008.jpg" width="216" /></a></div>Now I used the back arrow in the upper left to return all the way back to the Things screen. I turned on the SYLV 002 light and immediately the GE 001 light came on, too. Apparently, the rule system automatically implements the converse rule. If SYLV 002 is turned off, then GE 001 is turned off too.<br /><div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-ubnce_ULJQc/WoYz4eaJW5I/AAAAAAAApQo/8LvX4fBoC5MmFj7j5ZvvV2UehjvqQXw9ACLcBGAs/s1600/2018-02-15%2B17.27.20.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://2.bp.blogspot.com/-ubnce_ULJQc/WoYz4eaJW5I/AAAAAAAApQo/8LvX4fBoC5MmFj7j5ZvvV2UehjvqQXw9ACLcBGAs/s320/2018-02-15%2B17.27.20.jpg" width="320" /></a></div>This rule, however, works only from the perspective of the SYLV 002 light. The GE 001 light can be operated independently. So the rule doesn't cover all the possibilities. Making another rule from the perspective of the GE 001 light as the leader creates a loop that can have some undesirable behavior. We can exploit this for some silly fun. I made a set of four rules:<br /><ul><li><span>AEO 007 on ---&gt; SYLV 002 on</span></li><li><span>SYLV 002 on ---&gt; CREE 006 on</span></li><li><span>CREE 006 on ---&gt; GE 001 on</span></li><li><span>GE 001 on ---&gt; AEO 007 off</span></li></ul>I was expecting sequencing behavior, but what I got was somewhat reminiscent of linear but with some chaos added for good measure. It was hard to get it to stop. I eventually unplugged the power to the Raspberry Pi. On rebooting, I deleted the rules - I didn't think I had a practical application for such chaos.<br /><div class="separator" style="clear: both; text-align: center;"></div>What does this mean for rules? Well it means that it is possible to create infinitely looping dependencies. Think about how one would make two lights behave mutually exclusively: when one light is on, the other is off. An initial rule would be like the first example above where one follows another. The exception is that the target bulb is toggled to the opposite of the leader. That works fine from the perspective of the leader. However if the follower bulb is controlled independently, the leader's rule doesn't apply and both lights could be on at the same time. It is temping to add another rule where follower becomes the leader and vice versa. However, that sets up an infinite loop. Try it and you'll see what I mean.<br /><br />In my next blog posting, I'm going to add some color to this circus with some Phillips HUE lights.<br />Fri, 16 Feb 2018 05:16:59 +0000noreply@blogger.com (K Lars Lohn)Mozilla Marketing Engineering & Ops Blog: MozMEAO SRE Status Report - February 16, 2018https://mozilla.github.io/meao/2018/02/16/sre-statushttps://mozilla.github.io/meao/2018/02/16/sre-status/
<p>Here’s what happened on the MozMEAO SRE team from January 23 - February 16.</p>
<h3>Current work</h3>
<h4>SRE general</h4>
<h5>Load Balancers</h5>
<ul>
<li>We’ve tried several methods of automating our AWS Elastic Load Balancers, including <a href="https://www.terraform.io/">Terraform</a>, the <a href="https://aws.amazon.com/cli/">AWS CLI</a> and <a href="https://kubernetes.io/docs/concepts/services-networking/service/">Kubernetes-managed services</a>. Each method has proven to be quirky and error-prone, so we’re trying a <a href="https://github.com/mozmeao/infra/pull/714">Python-based automation system</a>. Additionally, the automation has the ability to <a href="https://github.com/mozmeao/infra/pull/727">generate code from existing ELBs in a given region</a>.</li>
</ul>
<h5>Cloudflare to Datadog service</h5>
<ul>
<li>The Cloudflare to Datadog service <a href="https://github.com/mozmeao/cloudflare-datadog/pull/12">has been converted</a> to use a non-<a href="https://helm.sh/">helm</a> based install, and is running in our new Oregon-B cluster.</li>
</ul>
<h5>Oregon-A cluster</h5>
<ul>
<li>We have a new Kubernetes cluster running in the us-west-2 AWS region that will run support.mozilla.org (SUMO) services as well as many of our other services.</li>
</ul>
<h4>Bedrock</h4>
<ul>
<li>Bedrock is moving to a <a href="https://github.com/mozilla/bedrock/pull/5334">“sqlitened” version</a> in our Oregon-B Kubernetes cluster that removes the dependency on an external database.</li>
</ul>
<h4>MDN</h4>
<ul>
<li>
<p>The cronjob that performs backups on attachments and other static media broke due to a misconfigured <code class="highlighter-rouge">LANG</code> environment variable. The base image for the cronjob <a href="https://github.com/mozmeao/infra/pull/711">was updated</a> and <a href="https://github.com/mozmeao/infra/pull/719">deployed</a>. We’ve also added some cron troubleshooting documentation as part of the same pull request.</p>
</li>
<li>
<p><a href="https://github.com/safwanrahman">Safwan Rahman</a> submitted <a href="https://github.com/mozilla/kuma/pull/4630">an excellent PR</a> to optimize Kuma document views 🎉🎉🎉.</p>
</li>
</ul>
<h4>support.mozilla.org (SUMO)</h4>
<ul>
<li>SUMO <a href="https://github.com/mozilla/kitsune/issues/2900">now uses</a> AWS <a href="https://aws.amazon.com/ses/">Simple Email Service (SES)</a> to send email.</li>
<li>We’re working on establishing a secure link between SCL3 and AWS for MySQL replication, which will help us signficantly reduce the amount of time needed in our migration window.</li>
<li>SUMO is now using a <a href="https://github.com/mozmeao/infra/pull/694">CDN</a> to <a href="https://github.com/mozilla/kitsune/issues/2949#issuecomment-363429101">host static media</a></li>
<li>We’re working on <a href="https://github.com/mozilla/kitsune/pull/3034">Python-based Kubernetes automation</a> for SUMO based on the <a href="http://www.pyinvoke.org/">Invoke library</a>. Automation includes web, cron and celery deployments, as well as rollout and rollback functionality.</li>
<li>Using the Python automation above, SUMO now runs in “vanilla Kubernetes” without <a href="https://deis.com/workflow/">Deis Workflow</a>.</li>
</ul>
<h3>Links</h3>
<ul>
<li><a href="https://github.com/mozmar/infra/projects/2">Github project tracking SRE work</a></li>
<li><a href="https://github.com/mozmar/infra/blob/master/docs/how_we_work.md">How MozMEAO SRE’s work</a></li>
</ul>Fri, 16 Feb 2018 00:00:00 +0000Firefox Test Pilot: Improving the web with small, composable toolshttps://medium.com/p/cb0ef7139750https://medium.com/firefox-test-pilot/improving-the-web-with-small-composable-tools-cb0ef7139750?source=rss----46b1a2ddb811---4
<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yHF3T_pFfV57yzu2oxcFMg.jpeg" /></figure><p><a href="https://screenshots.firefox.com/">Firefox Screenshots</a> is the first <a href="https://testpilot.firefox.com/">Test Pilot</a> experiment to graduate into Firefox, and it’s been surprisingly successful. You won’t see many people talking about it: it does what you expect, and it doesn’t cover new ground. Mozilla should do more of this.</p><h3>Small, Composable Tools</h3><p>One of the inspirations for Firefox Screenshots was <a href="https://blog.mozilla.org/ux/2015/02/save-share-revisit/">user research done in 2015</a>. This research involved interviews with a few dozen people about how they save, share, and recall information. I myself had a chance to be part of several house visits in Rochester, NY. We looked over people’s shoulders while they showed us how they worked.</p><p>My biggest takeaways from that research:</p><ul><li>There is a wide variety of how people manage their information, with many combinations of different tools and complex workflows</li><li>Everyone is pretty happy with what they are doing</li><li>People only want small, incremental changes</li><li>Screenshots are pretty popular</li></ul><p>It was surprising to see how complicated and sometimes clearly suboptimal people’s workflows were, while also understanding that each person was happy with what they did. They were happy because they weren’t looking for something new. At any moment most people are settled (<a href="https://www.nngroup.com/articles/satisficing/">satisficed</a>) on a process, and they have better things to do than constantly reconsider those choices.</p><p>After learning how they worked, we’d sometimes offer up alternatives and get reactions. The alternatives received lots of crickets. If you could add a tool to existing workflows then there might be interest, but there wasn’t interest in replacing tools unless perhaps it was a one-to-one match. People specifically weren’t interested in integrated tools, ones that improved the entire workflow.</p><p>And who among us hasn’t been burned by overenthusiasm for a fully integrated tool? It seems great, then it gets tiring just to keep track, annoying to try to get people to sign up so you can collaborate, some number of things don’t fit into the process, you’ve lost track of your old things, it just feels like work.</p><h3>Old Philosophies</h3><p>The <a href="https://en.wikipedia.org/wiki/Unix_philosophy#Origin">Unix philosophy</a>:</p><ul><li>Write programs that do one thing and do it well.</li><li>Write programs to work together.</li><li>Write programs to handle text streams, because that is a universal interface.</li></ul><p>This is still what works well, and still what people want! This is also what the web can provide and apps and silos cannot: open composability.</p><p>This isn’t the same as APIs and integrated tools: find and grep are not integrated, you don’t have to setup OAuth integration between tail and tee. Things work together because you use them together.</p><p>What would the Unix toolset look like on the web? Please <a href="http://www.ianbicking.org/blog/2018/02/web-small-composable-tools.html#disqus_thread">speculate</a>! <a href="https://docs.google.com/document/d/1NSO_Nl426o5Wuv896qk7vLudbf-z9FQSZf8fDBWPlwk/edit?usp=sharing">I’ve started structuring some of my own ideas into a set of notes</a>.</p><h3>Stop Being So Clever</h3><p>At the time of the user research myself and <a href="http://donovanpreston.com/">Donovan</a> had been working on an experiment in page capture — you could think of it like a personal archive.org. We added screenshotting as an entree into what felt like a more advanced tool.</p><p>In the end nothing is left of that original concept, and we just have plain screenshots. It hurt to see that all go. Screenshots are not exciting, and they are not innovative, and there is nothing very new about them. And clearly I needed to get over myself.</p><p>And so this is a lesson in humility: things don’t have to be new or novel or exciting to be useful. Screenshots is so un-new, so un-novel, so un-exciting that we aren’t even following along with the competition. Mozilla should spend more time here: behind the curve where the big players stopped caring and the little players have a hard time getting any attention. Behind the curve is where the web was a lot more like how Mozilla wants it to be.</p><p>There are lots of useful things back here, things that technophiles have appreciated but the wider population doesn’t know how to use. A pastebin. Site archival. Deep linking. Inline linking at all! Scraping. Clipboard management. Etherpad is still the best lightweight collaborative editor. Little stuff, things that don’t try to take over, things that don’t try to leverage the user for corporate benefit. This stuff is not very hard to make, and is affordable to run. Combine that with a commitment to keep the services competently maintained and openly interoperable, and there’s a lot of value to provide. And that’s what Mozilla is in it for: to be of service.</p><h3>Being Part Of The Web</h3><p>Screenshots was not easy to make. It was not <em>technically</em> difficult, but it was not easy.</p><p>Mozilla has long been reluctant to host user content. Firefox Sync is pointedly encrypted on the client. Before Screenshots the only unencrypted user content the corporation handled was the add-ons and themes on addons.mozilla.org.</p><p>Screenshots did not have to have a server component, and it did not have to allow people to upload or share shots within the tool. I take some pride in the fact that, despite all our cultural and legal attitudes at Mozilla, screenshots.firefox.com is a thing. It required a great deal of stubbornness on my part, and at times a pointed blindness to feedback.</p><p>In a small way Screenshots makes Mozilla part of the web, not just a window onto the web. This is a direction I think we should take: *.firefox.com links of all kinds should become normal, and you should know that on the other side of the link will be respectful content, it won’t be an avenue for manipulation, and you won’t be a product. Be the change you want to see, right?</p><p><em>Thanks to Wil Clouser and Jared Hirsch for feedback on this post.</em></p><p><em>Originally published at </em><a href="http://www.ianbicking.org/blog/2018/02/web-small-composable-tools.html"><em>www.ianbicking.org</em></a><em>.</em></p><img height="1" src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=cb0ef7139750" width="1" /><hr /><p><a href="https://medium.com/firefox-test-pilot/improving-the-web-with-small-composable-tools-cb0ef7139750">Improving the web with small, composable tools</a> was originally published in <a href="https://medium.com/firefox-test-pilot">Firefox Test Pilot</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>Thu, 15 Feb 2018 22:38:22 +0000Ian BickingFirefox Nightly: These Weeks in Firefox: Issue 32https://blog.nightly.mozilla.org/?p=342https://blog.nightly.mozilla.org/2018/02/15/these-weeks-in-firefox-issue-32/
<h3>Highlights</h3>
<ul>
<li>The WebExtension theme API now supports specifying colors for <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1412591">frame_inactive</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1426686">tab_loading</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1347184">icons and icons_attention</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1431189">button_background, button_background_hover and button_background_active</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1423762">toolbar_field_separator</a>.</li>
<li>We’re experimenting with “early blank first paint” to improve perceived start-up performance
<ul>
<li>The goal here is to paint an empty (about:blank) window as early as possible during startup. On slow computers this should let the user know that Firefox is starting and clicking the icon again isn’t needed. On faster computers it should improve the perception of startup performance.</li>
<li>This <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1336227">landed pref’ed off</a> last week and is available for testing in Nightlies. Feedback welcome, the pref to flip in about:config is browser.startup.blankWindow</li>
</ul>
</li>
<li>The <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1423896">All Bookmarks folder in the Library and the Star panel is now generated differently under-the-hood</a>. If you notice bugs when organizing bookmarks, please <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Toolkit&amp;component=Places">file a bug</a>.</li>
<li>Web Authentication on by default and shipping on Desktop in 60. [<a href="https://hacks.mozilla.org/2018/01/using-hardware-token-based-2fa-with-the-webauthn-api/">Hacks Post</a>] [<a href="https://blog.mozilla.org/press-de/2018/01/25/wie-hardware-token-basierte-zwei-faktor-authentifizierung-mit-der-webauthn-api-funktioniert/">Deutsch</a>]</li>
<li>We have <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1435296">reduced the precision of timers and clocks to 2ms</a> to make attacks like Spectre more difficult. Nightly today, Beta next week. Ping tjr or file a bug if you see weird behavior.</li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1395732">Dao has replaced the default “globe” favicon with a spiffy new Photon one</a>.</li>
<li>
<p></p><div class="wp-caption aligncenter" id="attachment_343"><a href="https://blog.nightly.mozilla.org/files/2018/02/4a0656c3-3972-4af9-920f-d9833e29aa4c.png"><img alt="Showing the new globe icon that we default to when no favicon is available." class="wp-image-343 size-large" height="62" src="https://blog.nightly.mozilla.org/files/2018/02/4a0656c3-3972-4af9-920f-d9833e29aa4c-e1518621655177-600x62.png" width="600" /></a><p class="wp-caption-text">Spiffy new globe!</p></div></li>
</ul>
<h3>Friends of the Firefox team</h3>
<p>(Give a shoutout/thanks to people for helping fix and test bugs. Introductions)</p>
<ul>
<li>Resolved bugs (excluding employees): <a href="https://mzl.la/2o14xUY">https://mzl.la/2o14xUY</a>
<ul>
<li>More than one bug fixed:
<ul>
<li>Ian Moody [:Kwan] (UTC+0)</li>
<li>Jeremy Lempereur</li>
<li>Michael Kohler [:mkohler]</li>
<li>Tim Nguyen :ntim</li>
<li>hemant</li>
</ul>
</li>
<li>New contributors (🌟 = First Patch!)
<ul>
<li>🌟 Nathan Watson <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1434262">got rid of some unneeded PlacesTestUtils code</a></li>
<li>🌟 Bogdan Pozderca [:bogdan] <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1412591">implemented the frame_inactive property</a> for the WebExtension theme-ing API</li>
<li>🌟 joseph.fergusson <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1429017">added Preferences spotlight support</a> for the Form Autofill doorhanger during first-time use</li>
<li>🌟 Zhengyi Lian <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1426686">made it possible to theme the tab loading indicator</a> colour for the WebExtension theme-ing API</li>
<li>🌟 George Dan <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1387632">renamed ProfileStorage.jsm to FormAutofillStorage.jsm</a> to make its purpose more clear</li>
<li>🌟 Dylan Stokes [:dyl] <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1347184">added support for changing toolbar button colours</a> for the WebExtension theme-ing API</li>
<li>🌟 Vivek <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1431189">added support for Google Chrome toolbar button color properties</a> in the webextension themes</li>
<li>🌟 Ashish Daulatabad <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1357791">helped sort out</a> some of our ancient OSHelperAppService code</li>
<li>🌟 Venkatesh Prabhu :vprabhu <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1434299">fixed a cursor glitch</a> in about:telemetry</li>
</ul>
</li>
</ul>
</li>
</ul>
<p> </p>
<h3>Project Updates</h3>
<h4>Add-ons</h4>
<ul>
<li>The runAt option to contentScripts.register <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1429425">now defaults to document_idle</a>.</li>
<li>The <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1344815">key combination to open a WebExtension sidebar is now shown</a> in the switcher dropdown and the sidebar menu.</li>
<li>Disabled pageActions <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1435992">no longer show a context menu item</a>.</li>
<li>Improved the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1420485">memory consumption of extensions which use tabs.insertCSS</a> significantly.</li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1403130">DOMNodes and cyclic objects can now be rendered</a> with the sidebar.setExpression API method.</li>
<li>The <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1421811">commands API now supports an update and a reset method</a> to dynamically change commands.</li>
<li>about:preferences now <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1429593">shows when an extension is controlling proxy preferences</a>.</li>
</ul>
<h4>Activity Stream</h4>
<ul>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1421441">Landed React 16</a>, which unlocks better bad state telemetry</li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1385944">Landed responsive version of Activity Stream</a> to take advantage of wider screens
<ul>
<li>
<p></p><div class="wp-caption aligncenter" id="attachment_344"><a href="https://blog.nightly.mozilla.org/files/2018/02/d2b28068-d86a-4187-854a-6cfeac9c3f65.png"><img alt="Activity Stream showing off its new responsive design" class="size-large wp-image-344" height="342" src="https://blog.nightly.mozilla.org/files/2018/02/d2b28068-d86a-4187-854a-6cfeac9c3f65-600x342.png" width="600" /></a><p class="wp-caption-text">Ooooooo responsive design</p></div></li>
</ul>
</li>
</ul>
<h4>Performance</h4>
<ul>
<li>Tab warming
<ul>
<li>Did you know that <a href="http://firefox-source-docs.mozilla.org/browser/base/tabbrowser/async-tab-switcher.html">there’s now documentation</a> for the async tab switcher? If you’ve ever been curious about how that thing works, check it out.</li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1432509">Patch to fix short-spinners</a> landed and bounced. Working on re-landing.</li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1423220">Patch to enable warming by default on Nightly</a> is ready to land once the above bug is fixed.</li>
</ul>
</li>
<li>paolo <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1434883">has been working on making our panel code properly async</a></li>
<li>Gijs <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1425602">has been driving add-ons / plug-ins blocklist work</a></li>
</ul>
<h4>Privacy/Security</h4>
<ul>
<li>Preloading Strict Transport Security for <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1418112">entire top-level domains (via the hstspreload.org list) is in 59</a>.</li>
<li>We are now <a href="https://blog.mozilla.org/security/2018/02/12/restricting-appcache-secure-contexts/">restricting AppCache to HTTPS</a>.</li>
</ul>
<h4><a href="https://wiki.mozilla.org/Firefox/Search">Search and Navigation</a></h4>
<h5>Address Bar &amp; Search</h5>
<ul>
<li>Florian has <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1371610">delayed creation of the autocomplete search components until the user starts searching</a>, this includes the Address Bar (startup perf)</li>
<li>Paolo has made <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1427350">the search bar use the richlistbox autocomplete</a> (same binding as the Address Bar)</li>
<li>Yuri Khan added an about:config pref to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1394304">always open Address Bar results in a new tab</a></li>
<li>Dao has <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1432716">grouped the “Show search suggestions ahead of history in address bar” checkbox with the other Search Suggestions checkboxes</a> in Preferences</li>
</ul>
<h5>Places</h5>
<ul>
<li>Thanks to the legacy transactions removal, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=406371">PlacesUtils is now a lazy getter in placesOverlay.xul</a>, an overlay included by every Window (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1436347">startup perf</a>)</li>
<li>Removed more legacy APIs:
<ul>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=539517">SetItemIndex</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1437040">GetItemIndex</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1432434">GetItemDateAdded and SetItemDateAdded</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1433305">GetItemLastModified</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1433983">setPostDataForBookmark and getPostDataForBookmark</a></li>
<li>Nathan Watson <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1434262">removed PlacesTestUtils.clearHistory()</a> (use PlacesUtils.history.clear() instead)</li>
<li>The <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1436966">bookmark-observers &amp; history-observers categories</a> have been removed (use places-init-complete instead)</li>
</ul>
</li>
<li>Kit simplified <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1436837">Syncing of the bookmark roots details</a></li>
<li>Doug Thayer is working on an experimental new <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1340498">Places notifications system</a> that should largely improve perf of history and bookmarks operations</li>
</ul>
<h5>More</h5>
<ul>
<li>Killed the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1167237">nsIBrowserGlue idl interface</a></li>
</ul>
<h4>Sync / Firefox Accounts</h4>
<ul>
<li>The Sync team is working with the <a href="https://mozilla-push-service.readthedocs.io/en/latest/">Push</a> and iOS teams to improve the Send Tab experience on mobile. 📲</li>
<li>Ed fixed a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1436637">deadlock</a> caused by simultaneous push notifications for sent tabs, and a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1436636">regression</a> in tracking tab sends. 🔓</li>
<li>Thom enabled <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1412332">password validation</a> on Nightly 🔑, and added a <a href="https://github.com/mhammond/aboutsync/pull/44">record editor</a> to About Sync ✏️.</li>
<li>More progress toward <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1433177">enabling new bookmark sync</a> by default. 📚 We’d like to fix a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1435446">storage thread hang</a> before encouraging everyone to dogfood.</li>
</ul>
<h4>Web Payments</h4>
<ul>
<li>Landed New WebPayments components
<ul>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1427936">List items UI</a></li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1427950">Shipping Address Picker</a></li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1429195">Payment Card selector</a></li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1429195">Shipping Option selector</a></li>
</ul>
</li>
</ul>Thu, 15 Feb 2018 20:16:55 +0000mconleyHacks.Mozilla.Org: Create VR on the Web using Unity3Dhttps://hacks.mozilla.org/?p=31931https://hacks.mozilla.org/2018/02/create-vr-on-the-web-using-unity3d/
<p><span style="font-weight: 400;">We are happy to announce our latest tool by Mozilla, </span><a href="https://www.assetstore.unity3d.com/#!/content/109152"><span style="font-weight: 400;">Unity WebVR Assets</span></a><span style="font-weight: 400;">. It is free to download and available now on the </span><a href="https://www.assetstore.unity3d.com/#!/content/109152"><span style="font-weight: 400;">Unity Asset Store</span></a><span style="font-weight: 400;">. This tool allows creators to publish and share VR experiences they created in Unity on the open web, with a simple URL or link. These experiences can then be viewed with any </span><a href="https://webvr.rocks/"><span style="font-weight: 400;">WebVR enabled browser</span></a><span style="font-weight: 400;"> such as Firefox (using the Oculus Rift or HTC VIVE) and Microsoft Edge (using a Windows Mixed Reality headset).</span></p>
<p></p>
<h4><a href="https://mozilla.github.io/unity-webvr-export/"><b>Try it out now!</b></a></h4>
<p><span style="font-weight: 400;">With the release of these assets, we hope to bridge the frictionless distribution, ease of use and accessibility of the Web with the best-in-class content creation tools from Unity. We believe this is a great fit for demos, marketing, news content, and any case where traditional application flows may be too time-consuming or troublesome for users.</span></p>
<p><span style="font-weight: 400;">Since the assets utilize the standards-based </span><a href="https://immersive-web.github.io/webvr/spec/1.1/"><span style="font-weight: 400;">WebVR API</span></a><span style="font-weight: 400;">, it removes the need for any platform specific SDKs and provides the ability to be responsive to different VR configurations. This enables the creation of experiences that can scale to different requirements, including everything from basic, desktop-based, non-VR environments (for example, using first-person-shooter-style controls) to fully immersive, room-scale, and motion-controlled VR configurations (for the <a href="https://webvr.rocks/htc_vive">HTC VIVE</a>, <a href="https://webvr.rocks/oculus_rift">Oculus Rift</a>, and <a href="https://webvr.rocks/windows_mixed_reality">Windows Mixed Reality</a> headsets).</span></p>
<h3><b>Using the WebVR Assets</b></h3>
<p><a href="https://assetstore.unity.com/packages/templates/systems/webvr-assets-109152"><img alt="" class="alignnone wp-image-31936 size-full" height="487" src="https://hacks.mozilla.org/files/2018/02/asset-store-1.png" width="821" /></a></p>
<p><span style="font-weight: 400;">Getting started couldn’t be easier! From within Unity, launch the Asset Store and search for <em>WebVR</em> to find the <a href="https://assetstore.unity.com/packages/templates/systems/webvr-assets-109152">WebVR Assets package</a>.</span></p>
<p></p>
<p><em><span style="font-weight: 400;">WebVR assets in action porting a Unity game to WebVR.</span></em></p>
<p><span style="font-weight: 400;">For full instructions on how to use these assets with your content, check out the </span><a href="https://github.com/mozilla/unity-webvr-export/blob/master/docs/project-setup.md"><span style="font-weight: 400;">Getting Started Guide</span></a><span style="font-weight: 400;">.</span></p>
<h3>We want to hear from you</h3>
<p><span style="font-weight: 400;">We’d love to hear about what you come up with using the WebVR-Assets. </span><b>Share your work</b><span style="font-weight: 400;"><strong> with us</strong> by using the </span><a href="https://twitter.com/search?f=tweets&amp;q=%23unitywebvr"><span style="font-weight: 400;">#unitywebvr</span></a><span style="font-weight: 400;"> Twitter hashtag.</span></p>
<p><span style="font-weight: 400;">The Unity WebVR Assets is an open-source project (licensed under Apache 2) available on </span><a href="https://github.com/mozilla/unity-webvr-export"><span style="font-weight: 400;">GitHub</span></a><span style="font-weight: 400;">:</span></p>
<p><span style="font-weight: 400;">You are encouraged to:</span></p>
<ul>
<li style="font-weight: 400;"><a href="https://github.com/mozilla/unity-webvr-export/issues"><span style="font-weight: 400;">View known issues</span></a></li>
<li style="font-weight: 400;"><a href="https://github.com/mozilla/unity-webvr-export/issues/new"><span style="font-weight: 400;">File an issue or feature request</span></a></li>
<li style="font-weight: 400;"><a href="https://github.com/mozilla/unity-webvr-export#contributing"><span style="font-weight: 400;">Contribute code or documentation to the project</span></a></li>
</ul>
<p><span style="font-weight: 400;">Reach out to us with any questions you may have or help you may need, and participate in the discussions on the WebVR Slack in the </span><a href="https://webvr.slack.com/messages/unity"><b>#unity</b><span style="font-weight: 400;"> channel</span></a><span style="font-weight: 400;">.</span></p>
<ul>
<li style="font-weight: 400;"><a href="https://webvr.rocks/slack"><span style="font-weight: 400;">Join the WebVR Slack</span></a><span style="font-weight: 400;"> (join the </span><a href="https://webvr.slack.com/messages/unity"><b>#unity</b></a><span style="font-weight: 400;"> channel)</span></li>
</ul>
<h3><b>Credits</b></h3>
<p><span style="font-weight: 400;">This project was heavily influenced by early explorations in using Unity to build for WebVR by </span><a href="https://github.com/gtk2k"><span style="font-weight: 400;">@gtk2k</span></a><span style="font-weight: 400;">.</span></p>
<p><span style="font-weight: 400;">Also, thanks to </span><a href="https://github.com/arturitu"><span style="font-weight: 400;">@arturitu</span></a><span style="font-weight: 400;"> for creating the </span><a href="https://github.com/aframevr/assets/tree/gh-pages/controllers/hands"><span style="font-weight: 400;">3D-hand models</span></a><span style="font-weight: 400;"> used for controllers in these examples.</span></p>Thu, 15 Feb 2018 17:13:32 +0000Casey YeeMozilla Reps Community: Reps On-boarding Teamhttp://blog.mozilla.org/mozillareps/?p=531https://blog.mozilla.org/mozillareps/2018/02/15/reps-on-boarding-team/
<p>As you already know from our discourse topic, we have created an Onboarding Screening Team.</p>
<p>The scope of this team is to help on evaluating the new applications to the Reps program by helping the Reps Council on this process.</p>
<p>In January we opened a call for the new team members on <a href="https://discourse.mozilla.org/t/do-you-want-join-the-onboarding-screening-team/24497">https://discourse.mozilla.org/t/do-you-want-join-the-onboarding-screening-team/24497</a></p>
<p>We were happily surprised with the number of applications we’ve got.</p>
<p>After a month the Reps Council has voted and has chosen the new members. Those are:</p>
<ul>
<li><a href="https://reps.mozilla.org/u/Mad_Maks/">Tim Maks van den Broek</a></li>
<li><a href="https://reps.mozilla.org/u/vi5halc/">Vishal Chavan</a></li>
<li><a href="https://reps.mozilla.org/u/akayannick98/">Aka Brou Yannick N</a></li>
<li><a href="https://reps.mozilla.org/u/gmontagu/">Gabriela Montagu</a></li>
</ul>
<p>On behalf of the Reps Council (and part of this team) I want to say thank you to the previous team that worked on 9 rounds of screening with evaluation of 39 applications.</p>
<p>These amazing people are:</p>
<ul>
<li><a href="https://reps.mozilla.org/u/michaelkohler/">Michael Kohler</a></li>
<li><a href="https://reps.mozilla.org/u/mijanur/">Mijanur Rahman</a></li>
<li><a href="https://reps.mozilla.org/u/Mte90/">Daniele Scasciafratte</a></li>
<li><a href="https://reps.mozilla.org/u/hossainalikram/">Hossain Al Ikram</a></li>
</ul>
<p>The new team will start to work soon (we have about 10 applications in queue) with the help of a Reps Council Member that will be focused on communications between applicants and the evaluation of this team.</p>
<p>If you want to congratulate your fellows Reps you can do it in this thread:</p>
<p><a href="https://discourse.mozilla.org/t/welcome-to-the-new-onboarding-screening-team-2018-1/25665">https://discourse.mozilla.org/t/welcome-to-the-new-onboarding-screening-team-2018-1/25665</a></p>
<p>More updates are coming so stay tuned!</p>Thu, 15 Feb 2018 16:57:59 +0000kpapadeaAir Mozilla: Reps Weekly Meeting, 15 Feb 2018https://air.mozilla.org/reps-weekly-meeting-20180215/https://air.mozilla.org/reps-weekly-meeting-20180215/
<p>
<img alt="Reps Weekly Meeting" class="wp-post-image" height="90" src="https://air.cdn.mozilla.net/media/cache/ea/95/ea959e7cca319261380787a7d8f66a94.png" width="160" />
This is a weekly call with some of the Reps to discuss all matters about/affecting Reps and invite Reps to share their work with everyone.
</p>Thu, 15 Feb 2018 16:00:00 +0000Air MozillaMozilla VR Blog: Create VR on the Web using Unity 3D5a85661ffb0518001815dc09https://blog.mozvr.com/webvr-using-unity/
<div class="kg-card-markdown"><img alt="Create VR on the Web using Unity 3D" src="https://blog.mozvr.com/content/images/2018/02/social-2.jpg" /><p>We are happy to announce Mozilla's latest tool for creating VR content, <a href="https://unity3d.com/">Unity 3D</a> <a href="https://www.assetstore.unity3d.com/#!/content/109152">WebVR Assets</a>. It is <a href="https://www.assetstore.unity3d.com/#!/content/109152">free to download</a> and available now on the <a href="https://www.assetstore.unity3d.com/#!/content/109152">Unity Asset Store</a>. This tool allows creators to publish VR experiences created in Unity and shared on the open Web, with the power of a URL or link. These experiences can then be viewed with any <a href="https://webvr.rocks/">WebVR-enabled browser</a> such as <a href="https://www.mozilla.org/en-US/firefox/new/">Firefox</a> (using the Oculus Rift or HTC VIVE) and Microsoft Edge (using a Windows Mixed Reality headset).</p>
<p><a href="https://mozilla.github.io/unity-webvr-export/"><img alt="Create VR on the Web using Unity 3D" src="https://blog.mozvr.com/content/images/2018/02/preview-1.gif" style="width: 100%;" /></a></p>
<p>With the release of <a href="https://www.assetstore.unity3d.com/#!/content/109152">this asset package</a>, we hope to bridge the frictionless distribution, ease of use, and accessibility of the Web with the best-in-class content-creation tools from Unity. We believe WebVR is a great fit for demos, marketing, news content, and any case where traditional application flows may be too time-consuming or troublesome for users.</p>
<p>Since the assets utilize the standards-based <a href="https://immersive-web.github.io/webvr/spec/1.1/">WebVR API</a>, it removes the need for any platform-specific SDKs and provides the ability to be responsive to different VR configurations. This enables the creation of experiences that can scale to different requirements, including everything from basic, desktop-based, non-VR environments (for example, using First-Person-Shooter-style controls) to fully immersive, room-scale, and motion-controlled VR configurations (for the <a href="https://webvr.rocks/htc_vive">HTC VIVE</a>, <a href="https://webvr.rocks/oculus_rift">Oculus Rift</a>, and <a href="https://webvr.rocks/windows_mixed_reality">Windows Mixed Reality</a> headsets).</p>
<h3>Using the <a href="https://www.assetstore.unity3d.com/#!/content/109152">WebVR Assets package</a></h3>
<p><a href="https://www.assetstore.unity3d.com/#!/content/109152"><img alt="Create VR on the Web using Unity 3D" src="https://blog.mozvr.com/content/images/2018/02/asset-store.png" /></a></p>
<p>Getting started couldn’t be easier! From within Unity, launch the Asset Store and search for <em>WebVR</em> to find the <a href="https://assetstore.unity.com/packages/templates/systems/webvr-assets-109152">WebVR Assets package</a>.</p>
<div style="width: 80%; margin-left: auto; margin-right: auto; text-align: center;">
<em><strong>WebVR Assets in action.</strong> A Unity game ported to WebVR.</em>
<br /><br /><br />
</div>
<p>For full instructions on how to use these assets with your content, check out the <a href="https://github.com/mozilla/unity-webvr-export/blob/master/docs/project-setup.md">Getting Started guide</a>.</p>
<h3>We want to hear from you!</h3>
<p>We’d love to hear about what you come up with using the WebVR-Assets. <strong>Share your work with us</strong> and use the <a href="https://twitter.com/search?f=tweets&amp;q=%23unitywebvr">#unitywebvr</a> Twitter hashtag.</p>
<p>Brought to you by Mozilla, the <a href="https://assetstore.unity.com/packages/templates/systems/webvr-assets-109152">Unity WebVR Assets</a> is an open-source project (licensed under <a href="https://github.com/mozilla/unity-webvr-export#license">Apache 2</a>) <a href="https://github.com/mozilla/unity-webvr-export">available on GitHub</a>.</p>
<ul>
<li><a href="https://github.com/mozilla/unity-webvr-export/issues">View known issues</a></li>
<li><a href="https://github.com/mozilla/unity-webvr-export/issues/new">File an issue or feature request</a></li>
<li><a href="https://github.com/mozilla/unity-webvr-export#contributing">Contribute code or documentation to the project</a></li>
</ul>
<p>Reach out to us with any questions you may have or help you may need, and participate in the discussions on the <a href="https://webvr.rocks/slack">WebVR Slack</a> in the <a href="https://webvr.slack.com/messages/unity">#unity channel</a>.</p>
<ul>
<li><a href="https://webvr.rocks/slack">Discuss with us on the WebVR Slack</a> (join the <a href="https://webvr.slack.com/messages/unity">#unity channel</a>)</li>
</ul>
<h3>Credits</h3>
<p>This project was heavily influenced by early explorations in using Unity to build for WebVR by <a href="https://github.com/gtk2k">@gtk2k</a>.</p>
<p>Also, thanks to <a href="https://github.com/arturitu">@arturitu</a> for creating the <a href="https://github.com/aframevr/assets/tree/gh-pages/controllers/hands">3D-hand models</a> used for controllers in these examples.</p>
</div>Thu, 15 Feb 2018 01:05:00 +0000Casey YeeThe Rust Programming Language Blog: Announcing Rust 1.24https://blog.rust-lang.org/2018/02/15/Rust-1.24.htmlhttps://blog.rust-lang.org/2018/02/15/Rust-1.24.html
<p>The Rust team is happy to announce a new version of Rust, 1.24.0. Rust is a
systems programming language focused on safety, speed, and concurrency.</p>
<p>If you have a previous version of Rust installed via rustup, getting Rust
1.24.0 is as easy as:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>rustup update stable
</code></pre></div></div>
<p>If you don’t have it already, you can <a href="https://www.rust-lang.org/install.html">get <code class="highlighter-rouge">rustup</code></a> from the
appropriate page on our website, and check out the <a href="https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1240-2018-02-15">detailed release notes for
1.24.0</a> on GitHub.</p>
<h3>What’s in 1.24.0 stable</h3>
<p>This release contains two very exciting new features: <code class="highlighter-rouge">rustfmt</code> and incremental compilation!</p>
<h5>rustfmt</h5>
<p>For years now, we’ve wanted a tool that automatically can reformat your Rust code to some sort
of “standard style.” With this release, we’re happy to announce that a <em>preview</em> of <code class="highlighter-rouge">rustfmt</code>
can be used with 1.24 stable. To give it a try, do this:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>rustup component add rustfmt-preview
</code></pre></div></div>
<p>There are two important aspects here: first, you’re using <code class="highlighter-rouge">rustup component
add</code> instead of <code class="highlighter-rouge">cargo install</code> here. If you’ve previously used <code class="highlighter-rouge">rustfmt</code> via
<code class="highlighter-rouge">cargo install</code>, you should uninstall it first. Second, this is a preview, as
it says in the name. <code class="highlighter-rouge">rustfmt</code> is not at 1.0 yet, and some stuff is being
tweaked, and bugs are being fixed. Once <code class="highlighter-rouge">rustfmt</code> hits 1.0, we’ll be
releasing a <code class="highlighter-rouge">rustfmt</code> component and deprecating <code class="highlighter-rouge">rustfmt-preview</code>.</p>
<p>In the near future, we plan on writing a post about this release strategy, as it’s big
enough for its own post, and is broader than just this release.</p>
<p>For more, please check out <a href="https://github.com/rust-lang-nursery/rustfmt"><code class="highlighter-rouge">rustfmt</code> on GitHub</a>.</p>
<h5>Incremental compilation</h5>
<p>Back in September of 2016 (!!!), we blogged about <a href="https://blog.rust-lang.org/2016/09/08/incremental.html">Incremental Compilation</a>.
While that post goes into the details, the idea is basically this: when you’re working on
a project, you often compile it, then change something small, then compile again. Historically,
the compiler has compiled your <em>entire</em> project, no matter how little you’ve changed the code.
The idea with incremental compilation is that you only need to compile the code you’ve actually
changed, which means that that second build is faster.</p>
<p>As of Rust 1.24, this is now <a href="https://github.com/rust-lang/cargo/pull/4817">turned on by default</a>.
This means that your builds should get faster! Don’t forget about <code class="highlighter-rouge">cargo check</code> when trying
to get the lowest possible build times.</p>
<p>This is still not the end story for compiler performance generally, nor incremental compilation
specifically. We have a lot more work planned in the future. For example, another change
related to performance hit stable this release:
<a href="https://github.com/rust-lang/rust/pull/46910"><code class="highlighter-rouge">codegen-units</code> is now set to 16 by default</a>.
One small note about this change: it makes builds faster, but makes the final binary a bit
slower. For maximum speed, setting <code class="highlighter-rouge">codegen-units</code> to <code class="highlighter-rouge">1</code> in your <code class="highlighter-rouge">Cargo.toml</code> is needed
to eke out every last drop of performance.</p>
<p>More to come!</p>
<h5>Other good stuff</h5>
<p>There’s one other change we’d like to talk about here: undefined behavior. Rust generally
strives to minimize undefined behavior, having none of it in safe code, and as little as
possible in unsafe code. One area where you could invoke UB is when a <code class="highlighter-rouge">panic!</code> goes
across an FFI boundary. In other words, this:</p>
<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">extern</span> <span class="s">"C"</span> <span class="k">fn</span> <span class="nf">panic_in_ffi</span><span class="p">()</span> <span class="p">{</span>
<span class="nd">panic!</span><span class="p">(</span><span class="s">"Test"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>This cannot work, as the exact mechanism of how panics work would have to be reconciled
with how the <code class="highlighter-rouge">"C"</code> ABI works, in this example, or any other ABI in other examples.</p>
<p>In Rust 1.24, <a href="https://github.com/rust-lang/rust/pull/46833">this code will now abort</a>
instead of producing undefined behavior.</p>
<p>See the <a href="https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1240-2018-02-15">detailed release notes</a> for more.</p>
<h4>Library stabilizations</h4>
<p>If you’re a fan of <code class="highlighter-rouge">str::find</code>, which is used to find a given <code class="highlighter-rouge">char</code> inside of a <code class="highlighter-rouge">&amp;str</code>, you’ll be
happy to see this pull request: <a href="https://github.com/rust-lang/rust/pull/46735">it’s now 10x faster</a>!
This is thanks to <code class="highlighter-rouge">memchr</code>. <code class="highlighter-rouge">[u8]::contains</code> <a href="https://github.com/rust-lang/rust/pull/46713">uses it too</a>,
though it doesn’t get such an extreme speedup.</p>
<p>Additionally, a few new APIs were stabilized this release:</p>
<ul>
<li><a href="https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.replace"><code class="highlighter-rouge">RefCell::replace</code></a></li>
<li><a href="https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.swap"><code class="highlighter-rouge">RefCell::swap</code></a></li>
<li><a href="https://doc.rust-lang.org/std/sync/atomic/fn.spin_loop_hint.html"><code class="highlighter-rouge">std::sync::atomic::spin_loop_hint</code></a></li>
</ul>
<p>Finally, these functions may now be used inside a constant expression, for example, to initialize a <code class="highlighter-rouge">static</code>:</p>
<ul>
<li><code class="highlighter-rouge">Cell</code>, <code class="highlighter-rouge">RefCell</code>, and <code class="highlighter-rouge">UnsafeCell</code>’s <code class="highlighter-rouge">new</code> functions</li>
<li>The <code class="highlighter-rouge">new</code> functions of the various <code class="highlighter-rouge">Atomic</code> integer types</li>
<li><code class="highlighter-rouge">{integer}::min_value</code> and <code class="highlighter-rouge">max_value</code></li>
<li><code class="highlighter-rouge">mem</code>’s <code class="highlighter-rouge">size_of</code> and <code class="highlighter-rouge">align_of</code></li>
<li><code class="highlighter-rouge">ptr::null</code> and <code class="highlighter-rouge">null_mut</code></li>
</ul>
<p>See the <a href="https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1240-2018-02-15">detailed release notes</a> for more.</p>
<h4>Cargo features</h4>
<p>The big feature of this release was turning on incremental compilation by default, as mentioned above.</p>
<p>See the <a href="https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1240-2018-02-15">detailed release notes</a> for more.</p>
<h3>Contributors to 1.24.0</h3>
<p>Many people came together to create Rust 1.24. We couldn’t have done it
without all of you. <a href="https://thanks.rust-lang.org/rust/1.24.0">Thanks!</a></p>Thu, 15 Feb 2018 00:00:00 +0000Mike Conley: Firefox Performance Update #1https://mikeconley.ca/blog/?p=2887https://mikeconley.ca/blog/2018/02/14/firefox-performance-update-1/
<p>In an attempt to fill the shoes of <a href="https://ehsanakhgari.org/category/blog">Ehsan’s</a> excellent Quantum Flow Newsletters<sup id="rf1-2887"><a href="https://mikeconley.ca/blog/2018/02/14/firefox-performance-update-1/#fn1-2887" rel="footnote" title="Like this one! Check out Ehsan’s blog for the rest of the series.">1</a></sup>, I’ve started to keep track of interesting performance bugs that have been tackled over the past little while.</p>
<p>I don’t expect I’ll be able to put together such excellent essays on performance issues in Firefox, but I can certainly try to help to raise the profile of folks helping to make Firefox faster.</p>
<p>Expect these to come out pretty regularly, especially as we continue to press our performance advantage over the competition. Maybe I’ll come up with a catchy title, too!</p>
<p>Anyhow, here’s the stuff that’s gone by recently that I’m pretty stoked about, performance-wise! To everybody in this list – thanks for making Firefox faster!</p>
<ul>
<li>Hiroyuki Ikezoe <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1419079">made it so that we use less CPU</a> when out-of-view elements and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1237454">visibility:hidden elements</a> are animating in certain cases</li>
<li>Mike Conley <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=888784">moved FormHistory database initialization and migration</a> off of the main thread</li>
<li>Bas Schouten <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1429623">made it so that we can get more detailed tracing information</a> from Gecko when profiling using VTune (example, RefreshDriver ticks). This should help us debug performance issues on Windows.</li>
<li>Ryan Hunt <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1430793">enabled experimental parallel painting for macOS</a>. This will hopefully allow us to perform painting more quickly in the future.</li>
<li>Florian Quèze <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1371610">made it so that we lazily instantiate the Search Service until the first search is started</a> instead of when the first search input is focused, which should help reduce the potential for jank when the user begins inputting a search</li>
<li>Gijs Kruitbosch <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1435609">reduced the size of the blocklist by ~50%</a> by removing the deprecated blocked certificates list. This means less work for Firefox to do in parsing that list soon after start-up. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1434302">He also made it so that only the blocked items that are relevant to the client application and platform are returned</a>, which means even fewer things to process. This should impact most Firefox users across the board, as the change occurred server-side where the blocklist is produced.</li>
<li>Marco Bonardo <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1361431">refactored PlacesDBUtils to not do main-thread IO</a> when Telemetry data is gathered.</li>
</ul>
<hr class="footnotes" /><ol class="footnotes"><li id="fn1-2887"><p>Like <a href="https://ehsanakhgari.org/blog/2017-09-21/quantum-flow-engineering-newsletter-25">this one</a>! Check out <a href="https://ehsanakhgari.org/category/blog">Ehsan’s blog</a> for the rest of the series. <a class="backlink" href="http://mikeconley.ca/blog/category/mozilla-2/feed/#rf1-2887" title="Jump back to footnote 1 in the text.">↩</a></p></li></ol>Wed, 14 Feb 2018 21:34:37 +0000MikeFirefox Test Pilot: Welcome Marnie to the Test Pilot Team!https://medium.com/p/4ab9c006150bhttps://medium.com/firefox-test-pilot/welcome-marnie-to-the-test-pilot-team-4ab9c006150b?source=rss----46b1a2ddb811---4
<figure><img alt="" src="https://cdn-images-1.medium.com/max/504/1*481ElRTjV7yFM7J9lcCONQ.png" /></figure><p>Late last year, the Test Pilot team welcomed a new engineering program manager, Marnie Pasciuto-Wood. In this post, Marnie talks about what it’s been like joining Mozilla and what keeps her busy and inspired outside of work.</p><p><strong>How would you describe your role on the Test Pilot team?</strong></p><p>Well, right now I feel like I’m still ramping up. Sometimes I think everything makes sense, but then BLAM, something sneaks up and surprises me. That said, I’m the Engineering Program Manager for the Test Pilot team. I started in mid-November, the day before the <a href="https://blog.mozilla.org/blog/2017/11/14/introducing-firefox-quantum/">Quantum launch</a>, and 3 weeks before the All-Hands in Austin.</p><p>If I were to describe my role in two words, I would say “cat wrangler,” where the cat is scheduling, planning, managing workloads, and agile project management for the various projects under the Test Pilot umbrella. I’m not there yet (see above, ramping up), but I’m working my way there.</p><p><strong>What does a typical day at Mozilla look like for you?</strong></p><p>Meetings! On the Test Pilot team, we have folks all over the world, so the mornings and early afternoons are stacked full of meetings. Towards the latter part of the afternoon, I have down time where I can deal with any tasks I need to accomplish before the next set of meetings start on the following day.</p><p><strong>Where were you before Mozilla?</strong></p><p>I was at my last company for 7.5 years. Throughout my tenure there, I had various roles: UX Designer, Technical Project Manager, and finally Engineering Program Manager which I loved the most. In that role, I ran the hosted, on premise, and cloud software programs for my company.</p><p><strong>On Test Pilot, what are you most looking forward to and why?</strong></p><p>I’m most excited about getting new, valuable, tested features into Firefox. I love that we have this platform to interact with our users and gather feedback about potential changes to the browser.</p><p><strong>What do you do, outside of work?</strong></p><p>I have two kids (15 and 9) that keep me pretty busy. I coach each of their soccer teams in both the spring and the fall. I also help out with their other activities: basketball, lacrosse, cross country, and Girl Scouts. In addition, every week I play goalie for my futsal team. Futsal is similar to soccer, but played indoors and only 5 v. 5. And finally, we’ve just started volunteering at the Oregon Food Bank once a week, which is amazing.</p><p><strong>M&amp;Ms or Reese’s Pieces?</strong></p><p>Reese’s Pieces…kept in the fridge.</p><p><strong>Tell me something most people at Mozilla don’t know about you.</strong></p><p>A few months before I joined Mozilla, my family and I spent 5 weeks traveling through western Europe and England. We flew into London and from there visited: Bath, Paris, Barcelona, Munich, Füssen, popped into Austria for 20 minutes, Bamberg, Rothenburg ob der Tauber, Berlin, Brussels, Bruges, Haarlem, and Amsterdam. It was an experience I’ll never forget, and we’re trying to plan another (shorter!) trip to a country we haven’t visited.</p><img height="1" src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=4ab9c006150b" width="1" /><hr /><p><a href="https://medium.com/firefox-test-pilot/welcome-marnie-to-the-test-pilot-team-4ab9c006150b">Welcome Marnie to the Test Pilot Team!</a> was originally published in <a href="https://medium.com/firefox-test-pilot">Firefox Test Pilot</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>Wed, 14 Feb 2018 21:13:37 +0000Sharon BautistaAir Mozilla: The Joy of Coding - Episode 128https://air.mozilla.org/the-joy-of-coding-episode-128/https://air.mozilla.org/the-joy-of-coding-episode-128/
<p>
<img alt="The Joy of Coding - Episode 128" class="wp-post-image" height="90" src="https://air.cdn.mozilla.net/media/cache/cb/68/cb68b6ac48452be7e7f25ddc7b63c959.png" width="160" />
mconley livehacks on real Firefox bugs while thinking aloud.
</p>Wed, 14 Feb 2018 18:00:00 +0000Air MozillaDaniel Pocock: What is the best online dating site and the best way to use it?357 at https://danielpocock.comhttps://danielpocock.com/what-is-the-best-online-dating-site
<div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Somebody recently shared this with me, this is what happens when you attempt to access Parship, an online dating site, from the anonymous <a href="https://www.torproject.org/projects/torbrowser.html">Tor Browser</a>.</p>
<p><img src="https://danielpocock.com/sites/danielpocock.com/files/parship-experian.png" /></p>
<p>Experian is basically a private spy agency. Their <a href="http://experian.co.uk/marketing-services/">website boasts</a> about how they can:</p>
<ul><li>Know who your customers are regardless of channel or device</li>
<li>Know where and how to reach your customers with optimal messages</li>
<li>Create and deliver exceptional experiences every time</li>
</ul><p>Is that third objective, an "exceptional experience", what you were hoping for with their dating site <a href="https://en.wikipedia.org/wiki/Honey_trapping">honey trap</a>? You are out of luck: <em>you are not the customer, you are the product</em>.</p>
<p>When the Berlin wall came down, people were horrified at what they found in the archives of the <a href="https://en.wikipedia.org/wiki/Stasi">Stasi</a>. Don't companies like Experian and Facebook gather far more data than this?</p>
<p><img src="https://danielpocock.com/sites/danielpocock.com/files/stasi-files.jpg" /></p>
<h3>So can you succeed with online dating?</h3>
<p>There are only three strategies that are worth mentioning:</p>
<ul><li>Access sites you can't trust (which includes <em>all</em> dating sites, whether free or paid for) using anonymous services like <a href="https://www.torproject.org/projects/torbrowser.html">Tor Browser</a> and anonymous email addresses. Use fake photos and fake all other data. Don't send your real phone number through the messaging or chat facility in any of these sites because they can use that to match your anonymous account to a real identity: instead, get an extra SIM card that you pay for and top-up with cash. One person told me they tried this for a month as an experiment, expediently cutting and pasting a message to each contact to arrange a meeting for coffee. At each date they would give the other person a card that apologized for their completely fake profile photos and offering to start over now they could communicate beyond the prying eyes of the corporation.</li>
<li>Join online communities that are not primarily about dating and if a relationship comes naturally, it is a bonus.</li>
<li>If you really care about your future partner and don't want your photo to be a piece of bait used to exploit and oppress them, why not expand your real-world activities?</li>
</ul></div></div></div>Wed, 14 Feb 2018 17:25:35 +0000Daniel.PocockThe Mozilla Blog: A Perspective: Firefox Quantum’s Tracking Protection Gives Users The Right To Be Curioushttps://blog.mozilla.org/?p=11248https://blog.mozilla.org/blog/2018/02/14/a-perspective-firefox-quantum-tracking-protection-gives-users-the-right-to-be-curious/
<p>In the physical world, we don’t wear our ID on our foreheads. This is convenient because we can walk around with a reasonable expectation of privacy and let our curiosity take us to interesting places. That shoe store you sauntered into because they had a pair that caught your eye has no idea who you are, where you live, or anything about you. More importantly, any attempt by that shoe store to have an employee follow you around would not only be impractical, but would be met with some serious side-eye from potential customers.</p>
<p>In the digital world, this isn’t true. Useful web technologies that make the sites you visit convenient and powerful can also be co-opted to track you wherever you go. The same incredible economies of scale that allow billions of people worldwide to stay connected also allow for the implementation of inexpensive and powerful methods of tracking. The profits from the sale of one pair of shoes allows the online shoe store to track thousands of people in the hopes of turning them into customers.</p>
<p>You would notice a beleaguered shoe store employee following you around, but you’re unlikely to notice most forms of online tracking. We’ve all had the experience where ads magically seem to follow you around, in a practice known as ‘retargeting’, and it’s often <a href="https://cdr.lib.unc.edu/indexablecontent/uuid:ceb8622f-1490-4078-ae41-4dc57f24e08b">unnerving </a>for users. However, the reality is that online tracking is mostly invisible. What’s more is that it’s used to create a profile that ties together as much data as possible in a practice called “<a href="http://freedom-to-tinker.com/2014/08/07/the-hidden-perils-of-cookie-syncing/">cookie syncing</a>” in an effort to predict your habits and preferences, in the hopes that the ads and recommendations you get are more likely to trigger your behavior in a desirable way.</p>
<p>Sometimes, information about you can be helpful. For instance, finding out what the most popular accessories are for your new phone can help you make better decisions about what to buy. Of greater concern is the lack of consent. In the real world, we generally look before we leap, but on the Internet, there’s no way to ‘preview’ the tracking of a site before you click a link. Often without your knowledge, information about you and your visit is compiled into an online profile that can be shared and sold to others without your knowledge.</p>
<p>What’s true for shoes also applies to ideas. Another often overlooked inconvenience is how tracking impacts people’s ability to explore new areas of the web. Against the backdrop of growing online bubbles and polarized media, if all the content you get recommendations for is in the same line of thought, how much are you able to explore what’s across the political line?</p>
<p>With <a href="https://marketingland.com/survey-shows-us-ad-blocking-usage-40-percent-laptops-15-percent-mobile-216324">40% of US internet users saying they have recently used ad blockers</a>, people clearly have an intuitive understanding that trackers and ads can be annoying, but do ad blockers do what they want?</p>
<p>Many in the tech world have been looking into this. When the companies providing the ad blocker are also the world’s biggest advertising networks, will it truly give you the tools to be inconspicuously curious?</p>
<p>Google Chrome’s approach is focused on annoying ads. Its ad blocker blocks ads, but it does nothing against invisible trackers or tracking ads that comply with the standards of the Better Ads Coalition, in which Facebook and Google are key partners. Even Apple’s Intelligent Tracking Protection has a set of rules that favor trackers operated by sites that users visit at least once a day. Unsurprisingly, Google and Facebook are the sites most likely to fall into this category.</p>
<p>If you’re not using Firefox Quantum today and care about your privacy, I encourage you to <a href="https://www.mozilla.org/en-US/firefox/channel/desktop/#firefox">give Firefox Quantum a try</a>. With <a href="https://blog.mozilla.org/firefox/tracking-protection-always-on/">Tracking Protection turned on</a>, you’ll get a web that lets you browse freely with fewer worries about pesky trackers, built by an independent organization that doesn’t run an ad network.</p>
<p>The post <a href="https://blog.mozilla.org/blog/2018/02/14/a-perspective-firefox-quantum-tracking-protection-gives-users-the-right-to-be-curious/" rel="nofollow">A Perspective: Firefox Quantum’s Tracking Protection Gives Users The Right To Be Curious</a> appeared first on <a href="https://blog.mozilla.org" rel="nofollow">The Mozilla Blog</a>.</p>Wed, 14 Feb 2018 17:00:05 +0000Nick NguyenAir Mozilla: Weekly SUMO Community Meeting, 14 Feb 2018https://air.mozilla.org/weekly-sumo-community-meeting-20180214/https://air.mozilla.org/weekly-sumo-community-meeting-20180214/
<p>
<img alt="Weekly SUMO Community Meeting" class="wp-post-image" height="90" src="https://air.cdn.mozilla.net/media/cache/4c/b1/4cb1b015e6a393e53dfc196726ec2561.png" width="160" />
This is the SUMO weekly call
</p>Wed, 14 Feb 2018 17:00:00 +0000Air MozillaHacks.Mozilla.Org: CSS Grid for UI Layoutshttps://hacks.mozilla.org/?p=31916https://hacks.mozilla.org/2018/02/css-grid-for-ui-layouts/
<p>CSS Grid is a great layout tool for content-driven websites that include long passages of text, and it has tremendous value for a variety of traditional UI layouts as well. In this article I’ll show you how to use CSS Grid to improve application layouts that need to respond and adapt to user interactions and changing conditions, and always have your panels scroll properly.</p>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout" rel="noopener" target="_blank">CSS Grid</a> builds website layouts. It lets web designers create beautiful dynamic layouts using just a tiny bit of supported code instead of the endless float hacks we’ve had to use for years. My friend and co-worker Jen Simmons has been <a href="http://jensimmons.com/writing">talking about</a> CSS Grid <a href="https://www.youtube.com/watch?v=kRYrbcGWjzU">for years</a>, tirelessly pushing to get it implemented in browsers, and her work has paid off. As of the end of last year, the current version of <i>every major browser, desktop and mobile, </i><a href="https://caniuse.com/#feat=css-grid"><i>supports CSS Grid</i></a>.</p>
<p>CSS Grid really is powerful, and you can build dynamic content driven websites easily, like in <a href="https://speckyboy.com/creative-examples-css-grid-layouts/">these examples</a>. However, Grid is good for more than laying out pretty blocks of content. Grid gives you full control over both dimensions of your layout, including scrolling. This means features we take for granted in native applications like collapsing side-panels and fixed toolbars are now trivial to implement. No more hacks and no more debugging. Grid just works.</p>
<p>I’ve been building web tools for years. Here’s a screenshot of a game building tool I made for my retro RPGs. When <a href="https://developer.mozilla.org/en-US/docs/Glossary/Flexbox" rel="noopener" target="_blank">Flexbox</a> first appeared I immediately started using it. I built complex layouts using nested horizontal and vertical boxes, with a few utility classes for things like scrolling and stretching.</p>
<p><a href="https://hacks.mozilla.org/files/2018/02/image4.png"><img alt="" class="alignnone wp-image-31917 size-large" height="309" src="https://hacks.mozilla.org/files/2018/02/image4-500x309.png" width="500" /></a></p>
<p>Flexbox has certainly made me more productive than absolutely positioned divs and float hacks, but it still has problems. Look at this closeup where panels come together. See how the footers on the left and right don’t line up?</p>
<p><a href="https://hacks.mozilla.org/files/2018/02/image5.png"><img alt="" class="alignnone wp-image-31918 size-full" height="84" src="https://hacks.mozilla.org/files/2018/02/image5.png" width="348" /></a></p>
<p>Here’s another screenshot. The toolbar is at the top of the drawing canvas, and according to my framework it should be fixed at the top, but the minute you start scrolling this happens. The toolbar disappears:</p>
<p><a href="https://hacks.mozilla.org/files/2018/02/image3.png"><img alt="" class="alignnone wp-image-31919 size-large" height="458" src="https://hacks.mozilla.org/files/2018/02/image3-500x458.png" width="500" /></a></p>
<p>Each of these problems can be fixed with more positioning and float hacks, but the result is always fragile. Every time I add a new panel I have to debug my layout all over again; searching to identify which <code>div</code> is grabbing the extra space during a resize. And the markup is ugly. The nested horizontal and vertical boxes become very complicated, and this example is only two levels deep. As interaction and functionality become more complex the design becomes even more challenging.</p>
<pre><code class="html">&lt;div class='hbox'&gt;
&lt;div class='vbox'&gt;
&lt;div class='hbox'&gt;header&lt;/div&gt;
&lt;div class='scroll'&gt;
&lt;div class='sidebar'&gt;sidebar&lt;/div&gt;
&lt;/div&gt;
&lt;div class='footer'&gt;footer&lt;/div&gt;
&lt;/div&gt;
&lt;div class=vbox&gt;
&lt;div class='hbox'&gt;button button
spacer label spacer button button &lt;/div&gt;
&lt;div class='center'&gt;main content&lt;/div&gt;
&lt;div class='hbox'&gt;the footer&lt;/div&gt;
&lt;/div&gt;
&lt;div class=vbox&gt;
&lt;div class=’hbox’&gt;header&lt;/div&gt;
&lt;div class=’scroll’&gt;
&lt;div class=’sidebar’&gt;sidebar&lt;/div&gt;
&lt;/div&gt;
&lt;div class=’footer’&gt;footer&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</code></pre>
<h3>Entering the Second Dimension</h3>
<p>The fundamental problem with Flexbox is that it is one dimensional. This makes Flexbox great for one dimensional uses, like toolbars and navbars, but it begins to fail when I need to align content both horizontally and vertically at the same time. Instead I need real <b>two</b> dimensional layout, which is why I need CSS Grid. Fundamentally Grid is 2D.</p>
<p>Here’s a similar kind of layout built with CSS Grid.</p>
<p><a href="https://hacks.mozilla.org/files/2018/02/image1.png"><img alt="" class="alignnone wp-image-31920 size-large" height="275" src="https://hacks.mozilla.org/files/2018/02/image1-500x275.png" width="500" /></a></p>
<p>Look closely at the bottom footers. They come together perfectly. And by using the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/grid-gap"><code>grid-gap</code></a> for the lines instead of adding borders to each panel, I don’t have to worry about inconsistent grid line widths. Everything just works.</p>
<p><a href="https://hacks.mozilla.org/files/2018/02/image2.png"><img alt="" class="alignnone wp-image-31921 size-large" height="204" src="https://hacks.mozilla.org/files/2018/02/image2-500x204.png" width="500" /></a></p>
<p>The biggest benefit I get from CSS Grid is adapting to changing conditions. My apps often have side panels. I need to make sure everything in the layout works regardless of whether the panels are expanded or collapsed, ideally without having to recalculate layout in JavaScript. Sidebars are made out of multiple components like headers and footers. All of these need to line up, regardless of which one is larger or smaller. Grid can do this too using a magic function called <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/minmax"><code>minmax()</code></a>.</p>
<p>If you’ve studied CSS Grid before then you know you can define your layout using <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-rows">templates</a> for the rows and columns. A template like <code>200px 1fr 200px</code> will give you 200px wide sidebars with a middle content area taking up the rest of the space. But what happens if the panel should collapse? Right now the column would stay at 200px, even though the content has shrunk. Instead we can use <code>minmax</code> with the <code>min-content</code> keyword for the max parameter.</p>
<pre><code class="css"><b>#grid </b>{
<b>display</b>: <b>grid</b>;
<b>box-sizing</b>: <b>border-box</b>;
<b>width</b>: 100<b>vw</b>;
<b>height</b>: 100<b>vh</b>;
<b>grid-template-columns</b>:
[<b>start</b>] <b>minmax</b>(<b>auto</b>, <b>min-content</b>)
[<b>center</b>]1<b>fr </b>
[<b>end</b>] <b>minmax</b>(<b>auto</b>,<b>min-content</b>);
<b>grid-template-rows</b>:
[<b>header</b>]2<b>em </b>
[<b>content</b>]1<b>fr </b>
[<b>footer</b>]2<b>em</b>;
<b>grid-gap</b>: 1<b>px</b>;
<b>background-color</b>: <b>black</b>;
}</code></pre>
<p>Now the grid column will be always be just wide enough to hold whatever is in any of the columns using their <i>minimum width</i>. Thus if one part of the column (say the header) is wider than the others, the column will expand to fit them all. If they become skinnier or disappear altogether, then the column will adjust accordingly. Essentially we have replicated the expanding/contracting behavior of Flexbox, but made it work with <i>everything</i> in the column together, not just one item. This is <i>real</i> 2D layout.</p>
<p>Here is the code for the rest of the demo.</p>
<pre><code class="css">
.<b>start </b>{
<b>grid-column</b>: <b>start</b>;
}
.<b>center </b>{
<b>grid-column</b>: <b>center</b>;
}
.<b>end </b>{
<b>grid-column</b>: <b>end</b>;
}
<b>header </b>{
<b>grid-row</b>: <b>header</b>;
}
<b>footer </b>{
<b>grid-row</b>: <b>footer</b>;
}
.<b>sidebar </b>{
<b>overflow</b>: <b>auto</b>;
}
</code></pre>
<pre><code class="html">
&lt;<b>div </b><b>id=</b><b>"grid"</b>&gt;
&lt;<b>header </b><b>class=</b><b>"start"</b>&gt;header&lt;/<b>header</b>&gt;
&lt;<b>header </b><b>class=</b><b>"center"</b>&gt;
&lt;<b>button </b><b>id=</b><b>"toggle-left"</b>&gt;toggle left&lt;/<b>button</b>&gt;
...
&lt;/<b>header</b>&gt;
&lt;<b>header </b><b>class=</b><b>"end"</b>&gt;header&lt;/<b>header</b>&gt;
&lt;<b>div </b><b>class=</b><b>"start sidebar"</b>&gt;sidebar&lt;/<b>div</b>&gt;
&lt;<b>div </b><b>class=</b><b>"center content"</b>&gt;the center content&lt;/<b>div</b>&gt;
&lt;<b>div </b><b>class=</b><b>"end sidebar"</b>&gt;
sidebar&lt;<b>br</b>/&gt;
...
&lt;/<b>div</b>&gt;
&lt;<b>footer </b><b>class=</b><b>"start"</b>&gt;left footer&lt;/<b>footer</b>&gt;
&lt;<b>footer </b><b>class=</b><b>"center"</b>&gt;center footer&lt;/<b>footer</b>&gt;
&lt;<b>footer </b><b>class=</b><b>"end"</b>&gt;right footer&lt;/<b>footer</b>&gt;
&lt;/<b>div</b>&gt;
</code></pre>
<p>To make the toggle buttons in the upper header actually hide the sidebars I added this code. Note that with modern DOM APIs and arrow functions we can essentially replicate JQuery in just a few lines:</p>
<pre><code class="js"><b>const </b><i>$ </i>= (selector) =&gt; <b><i>document</i></b>.querySelector(selector)
<b>const </b><i>$$ </i>= (selector) =&gt; <b><i>document</i></b>.querySelectorAll(selector)
<b>const </b><i>on </i>= (elem, type, listener) =&gt; elem.addEventListener(type,listener)
<i>on</i>(<i>$</i>(<b>'#toggle-left'</b>),<b>'click'</b>,()=&gt;{
<i>$$</i>(<b>".start"</b>).forEach((elem) =&gt; elem.classList.toggle(<b>'closed'</b>))
})
<i>on</i>(<i>$</i>(<b>'#toggle-right'</b>),<b>'click'</b>,()=&gt;{
<i>$$</i>(<b>".end"</b>).forEach((elem) =&gt; elem.classList.toggle(<b>'closed'</b>))
})
</code></pre>
<p>Also note that CSS Grid <i>does not</i> deprecate Flexbox. We still use Flexbox in the cases where it makes sense: namely one dimensional content like toolbars. Here are the styles that I’m using for my toolbars made out of headers:</p>
<pre><code class="html">
&lt;<b>header </b><b>class=</b><b>"center"</b>&gt;
&lt;<b>button </b><b>id=</b><b>"toggle-left"</b>&gt;toggle left&lt;/<b>button</b>&gt;
&lt;<b>button</b>&gt;open&lt;/<b>button</b>&gt;
&lt;<b>button</b>&gt;save&lt;/<b>button</b>&gt;
&lt;<b>span </b><b>class=</b><b>"spacer"</b>&gt;&lt;/<b>span</b>&gt;
&lt;<b>span</b>&gt;filename.txt&lt;/<b>span</b>&gt;
&lt;<b>span </b><b>class=</b><b>"spacer"</b>&gt;&lt;/<b>span</b>&gt;
&lt;<b>button</b>&gt;delete&lt;/<b>button</b>&gt;
&lt;<b>button </b><b>id=</b><b>"toggle-right"</b>&gt;toggle right&lt;/<b>button</b>&gt;
&lt;/<b>header</b>&gt;
<b>header </b>{
<b>background-color</b>: <b>#ccc</b>;
<b>display</b>: <b>flex</b>;
<b>flex-direction</b>: <b>row</b>;
}
.<b>spacer </b>{
<b>flex</b>: 1;
}
</code></pre>
<p>The <code>spacer</code> class makes an element take up all of the extra space. By using two spacers between the buttons I can make my toolbar shrink and grow as needed with the filename always in the middle. This is similar to native toolbars.</p>
<p>You can try out a demo live at this <a href="https://codepen.io/joshmarinacci/full/EQXyvM">Codepen</a>, then remix it to poke and prod.</p>
<p class="codepen">See the Pen <a href="https://codepen.io/joshmarinacci/pen/EQXyvM/">CSS Grid for UI Layouts</a> by Josh Marinacci (<a href="https://codepen.io/joshmarinacci">@joshmarinacci</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<p></p>
<p>CSS Grid is wonderful for designing interactive applications with two-dimensional complexity. We can keep the markup semantic. Panels and toolbar line up properly. The <code>grid-gap</code> gives us automatic borders. It adjusts our layout in complex ways without any JavaScript code, and it gives us control over both the horizontal and vertical. And we can do it all <b>without</b> using a heavy CSS framework.</p>
<p>Jen Simmons has started a new YouTube channel, <a href="https://www.youtube.com/channel/UC7TizprGknbDalbHplROtag">Layout Land</a> to help you grok how Grid works. If you work on web apps or any kind of richly interactive website, you should try out CSS Grid.</p>Wed, 14 Feb 2018 16:03:34 +0000Josh MarinacciQMO: Firefox 59 Beta 10 Testday, February 16thhttps://quality.mozilla.org/?p=50066https://quality.mozilla.org/2018/02/firefox-59-beta-10-testday-february-16th/
<p>Greetings Mozillians!</p>
<p>We are happy to let you know that <strong>Friday, February 16th</strong>, we are organizing <strong>Firefox 59 Beta 10 Testday</strong>. We’ll be focusing our testing on <i>Find Toolbar and Search Suggestions</i>.</p>
<p>Check out the detailed instructions via this <a href="https://public.etherpad-mozilla.org/p/testday-20180216">etherpad</a>.</p>
<p>No previous testing experience is required, so feel free to join us on <a href="http://widget01.mibbit.com/?server=irc.mozilla.org&amp;channel=%23qa">#qa IRC</a> channel where our moderators will offer you guidance and answer your questions.</p>
<p>Join us and help us make Firefox better!</p>
<p>See you on <strong>Friday</strong>!</p>Wed, 14 Feb 2018 10:55:33 +0000Bogdan MarisAir Mozilla: Martes Mozilleros, 13 Feb 2018https://air.mozilla.org/martes-mozilleros-20180213/https://air.mozilla.org/martes-mozilleros-20180213/
<p>
<img alt="Martes Mozilleros" class="wp-post-image" height="90" src="https://air.cdn.mozilla.net/media/cache/05/36/0536685608e291dcfa7ed22631076fdf.png" width="160" />
Reunión bi-semanal para hablar sobre el estado de Mozilla, la comunidad y sus proyectos. Bi-weekly meeting to talk (in Spanish) about Mozilla status, community and...
</p>Tue, 13 Feb 2018 22:00:00 +0000Air MozillaAir Mozilla: Bored and Brilliant: Finding Digital Equilibrium, with Manoush Zomorodihttps://air.mozilla.org/speaker-series-bored-and-brilliant-manoush-zomorodi/https://air.mozilla.org/speaker-series-bored-and-brilliant-manoush-zomorodi/
<p>
<img alt="Bored and Brilliant: Finding Digital Equilibrium, with Manoush Zomorodi" class="wp-post-image" height="90" src="https://air.cdn.mozilla.net/media/cache/f7/a4/f7a407ecb5973dea574fb21c6c79af6e.png" width="160" />
“Doing nothing” is vital in an age of constant notifications and digital distractions. Manoush consulted with neuroscientists and cognitive psychologists about the possibilities of “mind...
</p>Tue, 13 Feb 2018 18:00:00 +0000Air MozillaMozilla GFX: WebRender newsletter #14http://mozillagfx.wordpress.com/?p=1050https://mozillagfx.wordpress.com/2018/02/13/webrender-newsletter-14/
<p>Your favorite WebRender newsletter is ready. TL;DR: “fixed […], fixed […], fixed […], Glenn makes things even faster, fixed […], ad-lib”. Still mostly focusing on conformance and stability, although there is some performance work in progress as well.</p>
<p>Without further ado:</p>
<h3>Notable WebRender changes</h3>
<ul>
<li>Glenn <a href="https://github.com/servo/webrender/pull/2408">impemented</a> mip-mapping to get high quality down-sampling of large images.</li>
<li>Marting <a href="https://github.com/servo/webrender/pull/2403">cleaned</a> some code up.</li>
<li>Martin <a href="https://github.com/servo/webrender/pull/2402">made</a> some changes to how clip ids are assigned in order to make it possible to reduce the amount of hashing we do and improve performance.</li>
<li>Glenn <a href="https://github.com/servo/webrender/pull/2399">wrote</a> the initial implementation of an image brush shader which allows us to segment some images and improve performance in common cases (when there’s no tiling, spacing and repetition).</li>
<li>Lee <a href="https://github.com/servo/webrender/pull/2393">improved</a> the precision of text shadow with sub-pixel anti-aliasing.</li>
<li>Martin <a href="https://github.com/servo/webrender/pull/2392">improved</a> something about how hit testing and clipping interact (I don’t quite understand the ins and outs of this but it fixed a hit testing <a href="https://github.com/servo/webrender/issues/2383">issue</a>).</li>
<li>Glenn <a href="https://github.com/servo/webrender/pull/2391">avoided</a> requesting images from the texture cache if they are already present in the pre-render cache (saves wasted work and memory).</li>
<li>Kats <a href="https://github.com/servo/webrender/pull/2387">fixed</a> an issue in the yaml serializer.</li>
<li>Lee <a href="https://github.com/servo/webrender/pull/2386">implemented</a> passing variation dictionaries on CTF font creation.</li>
<li>Kvark <a href="https://github.com/servo/webrender/pull/2385">updated</a> wrench and the sample apps to use an up to date version of glutin instead of an old fork.</li>
<li>Glenn <a href="https://github.com/servo/webrender/pull/2382">implemented</a> partial rendering of off-screen pictures and render tasks.</li>
<li>Glenn <a href="https://github.com/servo/webrender/pull/2369">fixed</a> z-ordering of transformed content inside preserve-3d contexts.</li>
<li>Martin <a href="https://github.com/servo/webrender/pull/2367">made</a> hit testing consistent between frames.</li>
<li>Kats <a href="https://github.com/servo/webrender/pull/2358">avoided</a> rendering frames that are generated only for hit testing.</li>
<li>Nical <a href="https://github.com/servo/webrender/pull/2347">implemented</a> tracking removed pipelines to facilitate managing externally owned memory.</li>
<li>eeejay <a href="https://github.com/servo/webrender/pull/2323">implemented</a> color matrix filters, useful for accessibility and SVG color matrix filters.</li>
</ul>
<h3>Notable Gecko changes</h3>
<ul>
<li>Jeff and Gankro <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1362115">enabled</a> blob images by default.</li>
<li>Kats <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1421380">enabled</a> WebRender hit testing by default, and it fixed a whole lot of bugs.</li>
<li>Lee <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1396637">worked around</a> a sub-pixel glyph positioning issue.</li>
<li>Sotaro <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1413390">fixed</a> an issue with windowed plugins such as flash.</li>
<li>Sotaro <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1419293">tweaked</a> the swap chain type on Windows, and then <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1435995">fixed</a> an issue with this specific configuration not allowing us to do a graceful compositor fallback when the driver fails.</li>
<li>Heftig <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1424648">fixed</a> some text being rendered with the wrong metrics with some OpenType font collections by making sure we pass the proper face index to WebRender.</li>
<li>Jamie <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1429508">removed</a> a limitation on the size of recording DrawTargets we use with blob images.</li>
<li>Gankro <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1432309">fixed</a> a very bad rendering corruption by ensuring we make the right context current before rendering.</li>
<li>Andrew <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1432375">improved</a> the way shared memory is handled to avoid creating many file descriptors (and void running into the limit).</li>
<li>Kats <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1433579">fixed</a> a deadlock in the APZ code.</li>
<li>Kvark <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1433932">fixed</a> a crash with the capture debugging tool, and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1436190">another one</a>.</li>
<li>Kvark <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1434410">automated</a> including WebRender’s revision hash in the generated captures.</li>
<li>Kats <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1434996">fixed</a> an assertion happening when transaction ids don’t increase monotonically (can happen when we reuse a pres context from the back-forward cache).</li>
<li>Martin <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1435143">fixed</a> a bug in the way scroll ids are assigned and handled when building the display list for the root scroll frame.</li>
<li>Emilio <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1435618">fixed</a> a memory leak.</li>
<li>Kats <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1435282">fixed</a> an issue in the frame throttling logic which was messing with hit-testing.</li>
<li>Kats <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1436084">auditted</a> the reftests and marked new tests as passing.</li>
<li>Lee <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1436265">ensured</a> the ClearType usage setting isn’t ignored when WebRender is enabled.</li>
<li>Sotaro <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1436908">fixed</a> a memory leak.</li>
</ul>
<h3>Enabling WebRender in Firefox Nightly</h3>
<p>In about:config, just set “gfx.webrender.all” to true and restart the browser.</p>
<p>Note that WebRender can only be enabled in Firefox Nightly.</p>Tue, 13 Feb 2018 12:05:34 +0000NicalThis Week In Rust: This Week in Rust 221tag:this-week-in-rust.org,2018-02-13:blog/2018/02/13/this-week-in-rust-221/https://this-week-in-rust.org/blog/2018/02/13/this-week-in-rust-221/
<p>Hello and welcome to another issue of <em>This Week in Rust</em>!
<a href="http://rust-lang.org">Rust</a> is a systems language pursuing the trifecta: safety, concurrency, and speed.
This is a weekly summary of its progress and community.
Want something mentioned? Tweet us at <a href="https://twitter.com/ThisWeekInRust">@ThisWeekInRust</a> or <a href="https://github.com/cmr/this-week-in-rust">send us a pull request</a>.
Want to get involved? <a href="https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md">We love contributions</a>.</p>
<p><em>This Week in Rust</em> is openly developed <a href="https://github.com/cmr/this-week-in-rust">on GitHub</a>.
If you find any errors in this week's issue, <a href="https://github.com/cmr/this-week-in-rust/pulls">please submit a PR</a>.</p>
<h3>Updates from Rust Community</h3>
<h4>News &amp; Blog Posts</h4>
<ul>
<li>The community team is trying to improve outreach to meetup organisers. Please fill out their <a href="https://docs.google.com/forms/d/e/1FAIpQLSf52YXGhqBaHtCXtVna4iHYMK7IQaTqUW6V-ztsZC8C2TBInQ/viewform">call for contact info</a> if you are running or used to run a meetup.</li>
<li><a href="https://aturon.github.io/2018/02/09/amazing-week/">Closing out an incredible week in Rust</a>.</li>
<li><a href="http://smallcultfollowing.com/babysteps/blog/2018/02/09/maximally-minimal-specialization-always-applicable-impls/">Maximally minimal specialization: always applicable impls</a>.</li>
<li><a href="https://internals.rust-lang.org/t/announcing-the-2018-domain-working-groups/6737">Announcing the 2018 domain Working Groups</a>.</li>
<li><a href="https://boats.gitlab.io/blog/post/2018-02-07-async-iv-an-even-better-proposal/">Async/await IV: An even better proposal</a>.</li>
<li><a href="https://boats.gitlab.io/blog/post/2018-02-08-async-v-getting-back-to-the-futures/">Async/await V: Getting back to the futures</a>.</li>
<li><a href="https://www.rust-lang.org/pdfs/Rust-Tilde-Whitepaper.pdf">How Rust is Tilde’s competitive advantage</a>.</li>
<li><a href="http://rickyhan.com/jekyll/update/2018/02/06/rust-guitar-pedal-effects-dsp.html">Guitar effects in Rust</a>.</li>
<li><a href="http://blog.japaric.io/safe-dma/">Rust embedded: Memory safe DMA transfers</a>.</li>
<li><a href="https://github.com/BurntSushi/ripgrep/releases/tag/0.8.0">ripgrep 0.8.0 released: Configuration files, compressed file search, and true colors</a>.</li>
<li><a href="https://tokio.rs/blog/2018-02-tokio-reform-shipped/">Tokio reform and the road to 0.2</a>.</li>
<li><a href="http://fitzgeraldnick.com/2018/02/09/wee-alloc.html">Introducing a wee allocator for WebAssembly</a>.</li>
<li><a href="https://maikklein.github.io/rlsl-progress-report/">RLSL (Rust -&gt; SPIR-V compiler) progress report</a>.</li>
<li><a href="https://guillaumegomez.github.io/this-week-in-rust-docs/blog/this-week-in-rust-docs-92">This week in Rust docs 92</a>.</li>
<li>[podcast] <a href="https://rusty-spike.blubrry.net/2018/02/08/episode-18-feb-7-2018/">Rusty Spike Podcast - episode 18</a>. Reddit, a whitepaper, an academic paper, FOSDEM (and the lines), and AV1.</li>
<li>[podcast] <a href="http://www.newrustacean.com/show_notes/cysk/serde/">New Rustacean: Crates you should know: Serde</a>.</li>
<li><a href="https://blog.rustfest.eu/next-stop-paris">RustFest 2018</a>. 26 May - 27 May 2018 in Paris.</li>
</ul>
<h3>Crate of the Week</h3>
<p>This week sadly had to go without a crate for lack of votes.</p>
<p><a href="https://users.rust-lang.org/t/crate-of-the-week/2704">Submit your suggestions and votes for next week</a>!</p>
<h3>Call for Participation</h3>
<p>Always wanted to contribute to open-source projects but didn't know where to start?
Every week we highlight some tasks from the Rust community for you to pick and get started!</p>
<p>Some of these tasks may also have mentors available, visit the task page for more information.</p>
<ul>
<li><a href="https://www.rustaceans.org/findwork/starters">Get started with these beginner-friendly issues</a>.</li>
<li><a href="https://github.com/mgattozzi/github-rs/issues?q=is%3Aissue+is%3Aopen+label%3A%22Help+Wanted%22">github-rs: Pure Rust bindings to the Github API</a> needs help with some beginner-friendly issues.</li>
<li><a href="https://github.com/Keats/gutenberg/issues/205">gutenberg: Make content::Section hold references</a>. Gutenberg is an opinionated static site generator with everything built-in.</li>
</ul>
<p>If you are a Rust project owner and are looking for contributors, please submit tasks <a href="https://users.rust-lang.org/t/twir-call-for-participation/4821">here</a>.</p>
<h3>Updates from Rust Core</h3>
<p>117 pull requests were <a href="https://github.com/search?q=is%3Apr+org%3Arust-lang+is%3Amerged+merged%3A2017-02-05..2018-02-12">merged in the last week</a></p>
<ul>
<li>epochs: <a href="https://github.com/rust-lang/rust/pull/48014">rustc</a> and <a href="https://github.com/rust-lang/cargo/pull/5011">cargo</a> (RFC <a href="https://rust-lang.github.io/rfcs/2052-epochs.html">#2052</a>)</li>
<li><a href="https://github.com/rust-lang/rust/pull/47828">rustc: upgrade to LLVM 6</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48015">customizable extended tools</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48047">fix ICE for mismatched args on target without span</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48036">proc_macro: don't panic parsing <code>..=</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47752">implement <code>?</code> macro repetition</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48020">warn about more ignored bounds in type aliases</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47877">do not ignore lifetime bounds in Copy impls</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47613">add filtering options to <code>rustc_on_unimplemented</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48018">rustc: Add <code>#[rustc_args_required_const]</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48092">rustc_mir: insert a dummy access to places being matched on, when building MIR</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47657">emit data::Impl in save-analysis</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47978">ui tests: diff from old (expected) to new (actual) instead of backwards</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47957">NLL: improve <code>DefiningTy::Const</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47802">NLL: add false edges out of infinite loops</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47948">stabilize <code>use_nested_groups</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47944">implement <code>TrustedLen</code> for <code>Take&lt;Repeat&gt;</code> and <code>Take&lt;RangeFrom&gt;</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/48012">override <code>try_(r)fold</code> for RangeInclusive</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47631">add some APIs to ptr::NonNull</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47843">add <code>-Zteach</code> documentation</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47753">update book</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47959">fix rustdoc ICE on macros defined within functions</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/4834">make resolution backtracking smarter</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/5013">do not rename packages on <code>cargo new</code></a></li>
</ul>
<h4>New Contributors</h4>
<ul>
<li>bobtwinkles</li>
<li>Martin Algesten</li>
<li>Peter Hrvola</li>
<li>Yury Delendik</li>
</ul>
<h4>Approved RFCs</h4>
<p>Changes to Rust follow the Rust <a href="https://github.com/rust-lang/rfcs#rust-rfcs">RFC (request for comments)
process</a>. These
are the RFCs that were approved for implementation this week:</p>
<ul>
<li><a href="https://github.com/rust-lang/rfcs/pull/1909">RFC 1909: Unsized rvalues</a>.</li>
<li><a href="https://github.com/rust-lang/rfcs/pull/2145">RFC 2145: Type privacy and private-in-public lints</a>.</li>
<li><a href="https://github.com/rust-lang/rfcs/pull/2116">RFC 2116: Fallible collection allocation 1.0</a>.</li>
</ul>
<h4>Final Comment Period</h4>
<p>Every week <a href="https://www.rust-lang.org/team.html">the team</a> announces the
'final comment period' for RFCs and key PRs which are reaching a
decision. Express your opinions now. <a href="https://github.com/rust-lang/rfcs/labels/final-comment-period">This week's FCPs</a> are:</p>
<ul>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2299">Issues are not feature requests</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2056">Allow trivial constraints to appear in where clauses</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2166">impl-only-use</a>. The <code>use …::{… as …}</code> syntax can now accept <code>_</code> as alias to a trait to only import the implementations of such a trait.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2175">or-patterns in if / while let expressions</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2195">Formally define repr(u32, i8, etc...) and repr(C) on enums with payloads</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2250">Finalize syntax of <code>impl Trait</code> and <code>dyn Trait</code> with multiple bounds</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2298"><code>?</code> repetition in macro rules</a>.</li>
<li>[disposition: postpone] <a href="https://github.com/rust-lang/rfcs/pull/1546">Allow fields in traits that map to lvalues in impl'ing type</a>.</li>
<li>[disposition: postpone] <a href="https://github.com/rust-lang/rfcs/pull/1872">Fix the handling of uninhabited types in pattern matching</a>.</li>
<li>[disposition: postpone] <a href="https://github.com/rust-lang/rfcs/pull/1897">Unions 1.2</a>.</li>
<li>[disposition: postpone] <a href="https://github.com/rust-lang/rfcs/pull/2061">Allow destructuring of structs that implement Drop</a>.</li>
<li>[disposition: postpone] <a href="https://github.com/rust-lang/rfcs/pull/2148">Adding unsafe modules and unsafe blocks outside functions</a>.</li>
<li>[disposition: close] <a href="https://github.com/rust-lang/rfcs/pull/2221">Guard Clause Flow Typing</a>.</li>
<li>[disposition: close] <a href="https://github.com/rust-lang/rfcs/pull/2268">Legal double reference</a>.</li>
<li>[disposition: close] <a href="https://github.com/rust-lang/rfcs/pull/2144">Add match/in statements</a>.</li>
</ul>
<h4>New RFCs</h4>
<ul>
<li><a href="https://github.com/rust-lang/rfcs/pull/2325">Stable SIMD in Rust</a>.</li>
<li><a href="https://github.com/rust-lang/rfcs/pull/2328">Officially adopt Ferris as the mascot for the current epoch</a>.</li>
<li><a href="https://github.com/rust-lang/rfcs/pull/2333">Prior art</a>. A section to the RFC template where RFC authors may discuss the experience of other programming languages.</li>
<li><a href="https://github.com/rust-lang/rfcs/pull/2330">Amend RFC 0141 Lifetime elision: Mention deduplicated lifetimes</a>.</li>
</ul>
<h3>Upcoming Events</h3>
<p>The community team is trying to improve outreach to meetup organisers. Please fill out their <a href="https://docs.google.com/forms/d/e/1FAIpQLSf52YXGhqBaHtCXtVna4iHYMK7IQaTqUW6V-ztsZC8C2TBInQ/viewform">call for contact info</a> if you are running or used to run a meetup.</p>
<ul>
<li><a href="https://www.meetup.com/Cambridge-Rust-Meetup/events/mgtcwnyxdbtb/">Feb 15. Cambridge, UK - Rust Meetup</a>.</li>
<li><a href="https://www.meetup.com/mad-rs/events/247446699/">Feb 17. Chennai, India - Monthly Meetup - February</a>.</li>
<li><a href="https://www.meetup.com/Rust-Dev-in-Mountain-View/events/glnfcpyxdbxb/">Feb 18. Rust Dev in Mountain View - Open Table / Icebreaker: what projects are you working on</a>.</li>
<li><a href="https://www.meetup.com/Rust-in-Vilnius/events/244401223/">Feb 21. Vilnius, Lithuania - Rust Meetup #2</a>.</li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-community">Feb 21. Rust Community Team Meeting at #rust-community on irc.mozilla.org</a>.</li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-docs">Feb 21. Rust Documentation Team Meeting at #rust-docs on irc.mozilla.org</a>.</li>
<li><a href="https://internals.rust-lang.org/t/release-cycle-triage-proposal/3544">Feb 22. Rust release triage</a>.</li>
<li><a href="https://www.meetup.com/Rust-London-User-Group/events/246860921/">Feb 22. Rust London User Group - LDN Talks: February 2018</a>.</li>
<li><a href="https://www.meetup.com/RustMN/events/247512052/">Feb 22. Minneapolis, US - February 2018 Meetup</a>.</li>
<li><a href="https://www.meetup.com/Rust-Dev-in-Mountain-View/events/glnfcpyxdbxb/">Feb 25. Rust Dev in Mountain View - Open Table / Icebreaker: what projects are you working on</a>.</li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-content">Feb 27. Rust Community Content Subteam Meeting at #rust-content on irc.mozilla.org</a></li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-community">Feb 28. Rust Community Team Meeting at #rust-community on irc.mozilla.org</a>.</li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-docs">Feb 28. Rust Documentation Team Meeting at #rust-docs on irc.mozilla.org</a>.</li>
<li><a href="https://t.me/joinchat/EkKINhHCgZ9llzvPidOssA">Feb 28. Rust Events Team Meeting</a>.</li>
</ul>
<p>If you are running a Rust event please add it to the <a href="https://www.google.com/calendar/embed?src=apd9vmbc22egenmtu5l6c5jbfc%40group.calendar.google.com">calendar</a> to get
it mentioned here. Email the <a href="mailto:community-team@rust-lang.org">Rust Community Team</a> for access.</p>
<h3>Rust Jobs</h3>
<p><em>No jobs listed for this week.</em></p>
<p><em>Tweet us at <a href="https://twitter.com/ThisWeekInRust">@ThisWeekInRust</a> to get your job offers listed here!</em></p>
<h3>Quote of the Week</h3>
<p><em>No quote was selected for QotW.</em></p>
<p><a href="http://users.rust-lang.org/t/twir-quote-of-the-week/328">Submit your quotes for next week</a>!</p>
<p><em>This Week in Rust is edited by: <a href="https://github.com/nasa42">nasa42</a> and <a href="https://github.com/llogiq">llogiq</a>.</em></p>Tue, 13 Feb 2018 05:00:00 +0000TWiR ContributorsMichael Comella: Gmail Per-label Notifications for FastMailhttp://mcomella.xyz/blog/2018/gmail-per-label-notifications-for-fastmail.htmlhttp://mcomella.xyz/blog/2018/gmail-per-label-notifications-for-fastmail.html
<p>As someone who tries not to check their email often, I’ve relied on the Gmail Android app to notify me when urgent emails arrive. To do this, I:</p>
<ol>
<li>Use <a href="https://support.google.com/mail/answer/6579">Gmail filters</a> (through the web interface) to add a label to important messages: <code class="highlighter-rouge">notify me</code></li>
<li>Enable notifications in the Gmail app (Settings -&gt; me@gmail.com -&gt; Notifications)</li>
<li>Disable any “Label notifications” enabled by default (e.g. Inbox; Settings -&gt; me@gmail.com -&gt; Manage labels -&gt; Inbox -&gt; Label notifications)</li>
<li>Enable “label notifications” for <code class="highlighter-rouge">notify me</code></li>
</ol>
<p>Now I’ll receive notifications on my Android phone for urgent emails, labeled <code class="highlighter-rouge">notify me</code>, but not for other emails - great!</p>
<h3>FastMail</h3>
<p>I recently switched to <a href="https://www.fastmail.com/">FastMail</a>, which does not support notifications on a per-folder basis (folders stand in for labels), so I needed a new solution. I found one in <a href="https://www.fastmail.com/help/technical/sieve-notify.html">FastMail’s Sieve Notify extension</a>.</p>
<p>FastMail uses the <a href="https://www.fastmail.com/help/technical/sieve.html">Sieve</a> programming language to filter incoming emails. When a user uses the Rules GUI to create these filters, FastMail will generate the necessary Sieve scripts used behind the scenes. However, the GUI is limited so <a href="https://www.fastmail.com/help/technical/sieve-howto.html">they allow users to write custom sieve code</a> to filter mail in advanced ways.</p>
<p>Their Sieve implementation comes with <a href="https://www.fastmail.com/help/technical/sieve.html#extensions">many extensions</a>, one of which is the Notify extension. Notify, when called from a Sieve script, can launch a notification from the FastMail mobile app with the user-specified custom text. Note that Notify can also be used to forward an email or send a message through twilio, Slack, or IFTTT.</p>
<p>Here are the basic steps to get Notify working:</p>
<ol>
<li>Write a custom Sieve script (through the web interface) to run Notify on desired emails (Settings -&gt; Rules -&gt; Edit custom sieve code; there will also be auto-generated Sieve code here)</li>
<li>Disable notifications (yes disable!) in the FastMail app: this stops notifications for mail that isn’t using Notify (Device Settings -&gt; Notifications)</li>
</ol>
<p>Here’s an example Sieve script to open a notification for mail from <code class="highlighter-rouge">a@b.com</code> or <code class="highlighter-rouge">x@y.xyz</code>, keep the message, and stop futher filtering:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>if
anyof(
address :is "From" "a@b.com",
address :is "From" "x@y.xyz"
)
{
# Notify the app with the specified text
notify :method "app" :options ["From","Full"] :message "$from$ / $subject$ / $text[500]$";
# Keep the message and don't go through additional filters.
# Without "keep", "stop" will discard the message so be careful!
keep;
stop;
}
</code></pre></div></div>
<p>See additional details at <a href="https://www.fastmail.com/help/technical/sieve-notify.html">the Notify documentation here</a>. I paste this script in the bottom-most custom sieve section (below the rules generated from the Organize Rules GUI) though it could be moved anywhere. Once the script is added and notifications are disabled, the FastMail app will send notifications if and only if they match the Notify filters!</p>
<p>This solution comes with some pros:</p>
<ul>
<li>Unlike the alternative solution below, notifications are independent of folders so all mail can end up in the <code class="highlighter-rouge">Inbox</code></li>
<li>In theory, it will work automatically when switching between iOS and Android</li>
</ul>
<p>And cons (on Android, at least):</p>
<ul>
<li>Each email will create a new notification: they don’t batch together</li>
<li>Clicking on a notification does not launch the app: it must be opened from the launcher</li>
<li>The notifications have no quick actions (e.g. reply, archive, delete)</li>
<li>With my Sieve order, other filters will take precedence and may prevent Notify from running. This can be fixed.</li>
</ul>
<h4>An alternative solution</h4>
<p>Before finding this solution, I first came up with another: I installed a local mail client that could enable/disable notifications at the folder level (<a href="https://k9mail.github.io/">K-9 Mail</a>) and mimicked the Gmail app solution. This was unsatisfactory to me because it required me to check two folders for my new mail - <code class="highlighter-rouge">Inbox</code> and <code class="highlighter-rouge">notify me</code> - since a FastMail message can only exist in one folder, unlike Gmail labels. This solution also forced me to configure an unfamiliar client (K-9 isn’t simple…) and to trust it with login credentials.</p>Tue, 13 Feb 2018 00:00:00 +0000Mozilla Security Blog: Restricting AppCache to Secure Contextshttps://blog.mozilla.org/security/?p=2296https://blog.mozilla.org/security/2018/02/12/restricting-appcache-secure-contexts/
<p>The Application Cache (AppCache) interface provides a caching mechanism that allows websites to run offline. Using this API, developers can specify resources that the browser should cache and make available to users offline. Unfortunately, AppCache has limitations in revalidating its cache, which allows attackers to trick the browser into never revalidate the cache by setting a manifest to a malformed cache file. Removing AppCache over HTTP connections removes the risk that users could see stale cached content that came from a malicious connection indefinitely.</p>
<p><em>Consider the following attack scenario: A user logs onto a coffee shop WiFi where an attacker can manipulate the WiFi that is served over HTTP. Even if the user only visits one HTTP page over the WiFi, the attacker can plant many insecure iframes using AppCache which allows the attacker to rig the cache with malicious content manipulating all of those sites indefinitely. Even a cautious user who decides only to login to their websites at home is at risk due to this stale cache.</em></p>
<p>In line with our previous stated intents of <a href="https://blog.mozilla.org/security/2015/04/30/deprecating-non-secure-http/">deprecating HTTP</a> and <a href="https://blog.mozilla.org/security/2018/01/15/secure-contexts-everywhere/">requiring HTTPS for all new APIs</a>, we are continuing to remove features from sites served over insecure connections. This means that websites wishing to preserve all their functionality should transition their sites to using TLS encryption as soon as possible.</p>
<p>In Firefox 60+ Beta and Nightly, Application Cache access from HTTP pages is denied. Starting with Firefox 62 Release, Application Cache over HTTP will be <a href="https://groups.google.com/forum/#!topic/mozilla.dev.platform/qLTTpdzcDkw">fully removed for all release channels</a>. All other browsers have also stated their intent to remove: <a href="https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/ANnafFBhReY/1Xdr53KxBAAJ">Chrome</a>, <a href="https://twitter.com/patrickkettner/status/961999450016239616">Edge</a>, <a href="https://bugs.webkit.org/show_bug.cgi?id=182442">WebKit</a>. This change will also be reflected in the <a href="https://github.com/whatwg/html/issues/3440">HTML standard</a>.</p>
<p>Going forward, Firefox will deprecate more APIs over insecure connections in an attempt to increase adoption of HTTPS and improve the safety of the internet as a whole.</p>
<p>The post <a href="https://blog.mozilla.org/security/2018/02/12/restricting-appcache-secure-contexts/" rel="nofollow">Restricting AppCache to Secure Contexts</a> appeared first on <a href="https://blog.mozilla.org/security" rel="nofollow">Mozilla Security Blog</a>.</p>Mon, 12 Feb 2018 22:54:02 +0000Jonathan KingstonThe Mozilla Blog: Update: Mozilla Will Re-File Suit Against FCC to Protect Net Neutralityhttps://blog.mozilla.org/?p=11244https://blog.mozilla.org/blog/2018/02/12/update-mozilla-will-re-file-suit-fcc-protect-net-neutrality/
<p>Protecting net neutrality is core to the internet and crucial for people’s jobs and everyday lives. It is imperative that all internet traffic be treated equally, without discrimination against content or type of traffic — that’s the<a href="https://blog.mozilla.org/blog/2017/09/15/busting-myth-net-neutrality-hampers-investment/"> how the internet was built</a> and what has made it one of the greatest inventions of all time.</p>
<h3><b>What happened?</b></h3>
<p>Last month,<a href="https://blog.mozilla.org/wp-content/uploads/2018/01/AS-FILED-Mozilla-Protective-Petition-16Jan2018-1.pdf"> Mozilla filed</a> a petition against the Federal Communications Commission for its disappointing decision to overturn the 2015 Open Internet Order because we believe it violates federal law and harms internet users and innovators.</p>
<p>We <a href="https://blog.mozilla.org/blog/2018/01/16/mozilla-files-suit-fcc-protect-net-neutrality/">said that we believed</a> the filing date should be later (while the timing seemed clear in the December 2017 draft order from the FCC, federal law is more ambiguous). We urged the FCC to determine the later date was appropriate, but we filed on January 16 because we are not taking any chances with an issue of this importance.</p>
<p>On Friday, the FCC filed to dismiss this suit and require us to refile after the order has been published in the Federal Register, as we had anticipated.</p>
<h3><b>What’s next?</b></h3>
<p>We will always fight to protect the open internet and will continue to challenge the FCC’s decision to destroy net neutrality in the courts, in Congress, and with our allies and internet users.</p>
<p>The FCC’s decision to destroy net neutrality rules is the result of broken processes, broken politics, and broken policies. It will end the internet as we know it, harm<a href="https://blog.mozilla.org/blog/2017/06/06/new-mozilla-poll-americans-political-parties-overwhelmingly-support-net-neutrality/"> internet users</a> and small businesses, erode free speech, competition, innovation and user choice in the process. In fact, it really only benefits large Internet Service Providers.</p>
<p>We will re-file our suit against the FCC at the appropriate time (10 days after the order is published in the Federal Register).</p>
<h3><b>What can you do?</b></h3>
<p>You can <a href="https://advocacy.mozilla.org/en-US/net-neutrality/">call your elected officials</a> and urge them to support net neutrality and an open internet. Net neutrality is not a partisan or U.S. issue and the decision to remove protections for net neutrality is the result of broken processes, broken politics, and broken policies. We need politicians to decide to protect users and innovation online rather than increase the power of a few large ISPs.</p>
<p>The post <a href="https://blog.mozilla.org/blog/2018/02/12/update-mozilla-will-re-file-suit-fcc-protect-net-neutrality/" rel="nofollow">Update: Mozilla Will Re-File Suit Against FCC to Protect Net Neutrality</a> appeared first on <a href="https://blog.mozilla.org" rel="nofollow">The Mozilla Blog</a>.</p>Mon, 12 Feb 2018 21:49:12 +0000Denelle DixonK Lars Lohn: Lars and the Real Internet of Things - Part 2tag:blogger.com,1999:blog-12340845.post-5369857614862705647http://www.twobraids.com/2018/02/lars-and-real-internet-of-things-part-2.html
<br /><div style="text-align: left;">In part 1 of this missive, I talked about my own checkered history of trying to control devices in my home. Today I'm going to talk about setting up the Things Gateway software. <br /><br /><b>Disclaimers and Setting Expectations</b>: The Things Gateway is an experimental proof of concept, not a polished commercial product. It is aimed at the <i>makers</i> of the technology world, not someone expecting an effortless and flawless plug-and-play experience. You will encounter glitches and awkward interfaces. You may even have to interact with the Linux command line. <br /><br />The Mozilla IoT Gateway is not yet either a functional equivalent or replacement for the commercial products. There are features missing that you will find in commercial products. It is the hope of Mozilla that this project will evolve into a full featured product, but that will take time and effort. <br /><br />This is where we invite everyone in. The Things Gateway is open source. We encourage folks to participate, help add the missing features, help add support for more and more IoT capable things.</div><div style="text-align: left;"><br /></div><div style="text-align: left;"><b>Goal</b>: <i>I want to get the Things Gateway by Mozilla up and running on a headless Raspberry Pi. It will communicate with a smart light bulb and a smart plugin switch using a Zigbee adapter. The IoT system will be configured for operation exclusively on the local network with no incoming or outgoing communication with the Internet.</i><br /><br /><a href="https://4.bp.blogspot.com/-ZODwqrcG2To/Wn8f2i9uVnI/AAAAAAAApMs/h2HqtC5V20cYTYDje5vBAn_s33cC60tbwCLcBGAs/s1600/2018-02-09%2B15.56.36.jpg" style="float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="240" src="https://4.bp.blogspot.com/-ZODwqrcG2To/Wn8f2i9uVnI/AAAAAAAApMs/h2HqtC5V20cYTYDje5vBAn_s33cC60tbwCLcBGAs/s320/2018-02-09%2B15.56.36.jpg" width="320" /></a><br />Okay, we've had the history, the disclaimers and the goal, let's start controlling things. If there are terms that I use and you don't know what they mean, look to the <a href="https://github.com/mozilla-iot/wiki/wiki/Glossary-of-Terms">Mozilla Iot Glossary of Terms</a>.<br /><br />To work with the Things Gateway software, you're going to need some hardware. I'm going to demonstrate using the ZigBee protocol and devices. To follow exactly what I'm going to do, you'll need to acquire the hardware or equivalents in the chart below. In future articles, I'm going show how to add Z-Wave, Philips Hue, Ikea TRÅDFRI and TPLink hardware. Then I'll get into programming to add support to devices we've not even thought of yet.<br /><br /></div><div style="text-align: left;"><br /></div><table border="1" style="margin-left: 0px; margin-right: auto; text-align: left;"><tbody><tr><th>Item</th><th>What's it for?</th><th>Where I got it</th></tr><tr><td>A laptop or desktop PC</td><td>This will be used to download the software and create the media that will boot the Raspberry Pi</td><td>I'm going to use my Linux workstation, any PC will do</td></tr><tr><td>µSD Card Reader</td><td>Needed only if there is no other way for the Desktop or Laptop to write to a µSD card</td><td>I used a Transcend TS-RDF5K that I bought on Amazon years ago </td></tr><tr><td>Raspberry Pi Model 3 B</td><td>This is the single board computer that will run the Things Gateway. </td><td>These are available from many vendors like Amazon and Adafruit</td></tr><tr><td>5V µUSB Power Supply</td><td>This supplies power to the Raspberry Pi</td><td>I had a spare one lying around, but you can probably get one from the vendor that sold the Raspberry Pi to you.</td></tr><tr><td>µSD Card</td><td>This will essentially be the Raspberry Pi's hard drive</td><td>I got mine in the checkout isle of the grocery store, it needs to be at least 4G </td></tr><tr><td>DIGI XStick</td><td>This allows the Raspberry Pi to talk the ZigBee protocol - there are several models, make sure you get the XU-Z11 model.</td><td>The only place that I could find this was <a href="https://www.mouser.com/ProductDetail/888-XU-Z11?r=888-XU-Z11">Mouser Electronics</a></td></tr><tr><td>CREE Connected ZigBee Compatible Light Bulb </td><td>It's a thing to control</td><td>I got one from my local <a href="https://www.homedepot.com/p/Cree-Connected-60W-Equivalent-Soft-White-A19-Dimmable-LED-Light-Bulb-BA19-08027OMF-12CE26-1C100/206593642">Home Depot</a></td></tr><tr><td>Sylvania SMART+ Plug ZigBee Compatible Appliance Switch</td><td>It's a thing to control</td><td>I got this one from <a href="https://www.amazon.com/SYLVANIA-ZigBee-Smart-SmartThings-Assistant/dp/B01M6UM8QD/ref=sr_1_3?ie=UTF8&amp;qid=1518119938&amp;sr=8-3&amp;keywords=sylvania+zigbee">Amazon</a></td></tr></tbody></table><br /><div style="text-align: left;"><b>Step 1</b>: I downloaded the Things Gateway image file by pressing the Download button on the <a href="https://github.com/mozilla-iot/gateway/releases/download/0.3.0/gateway-0.3.0.img.zip">Build Your Own Web of Things</a> page while using my Linux Workstation. You should use a desktop or laptop. You can be successful using any OS, I just happen to be a Linux geek.<br /><br /><b>Step 2</b>: I flashed the image onto my µSD card using my µSD Card Reader. <i><b>General instructions can be found on the <a href="https://www.raspberrypi.org/documentation/installation/installing-images/">installing images page</a></b></i>. Since I'm using a Linux machine, I just used shell based tools like, <a href="http://manpages.ubuntu.com/manpages/bionic/man8/lsblk.8.html">lsblk</a> and <a href="http://manpages.ubuntu.com/manpages/xenial/en/man1/dd.1posix.html">dd</a>. I had to identify my µSD card by its size. I knew it would be the smallest device on my machine, so I identified it as the last on the lsblk list: <span style="font-family: monospace;">sdh</span>. Be very careful that you select the correct disk. <b><i>This is a very sharp knife, choosing the wrong disk could be a disaster. Proceed at your own risk.</i></b><br /><blockquote style="background-color: black; color: #777777;"><tt><span style="font-family: monospace; font-size: small;">bozeman:~ ᚥ <span style="color: greenyellow;">cd Downloads</span><br />bozeman:~/Downloads ᚥ <span style="color: greenyellow;">unzip gateway-0.3.0.img.zip</span><br />bozeman:~/Downloads ᚥ <span style="color: greenyellow;">lsblk | grep disk</span><br />sda 8:0 0 894.3G 0 disk<br />sdb 8:16 0 1.8T 0 disk<br />sdc 8:32 0 2.7T 0 disk<br />sdd 8:48 0 2.7T 0 disk<br />sde 8:64 0 2.7T 0 disk<br />sdf 8:80 0 2.7T 0 disk<br />sdh 8:112 1 14.4G 0 disk<br />bozeman:~/Downloads ᚥ <span style="color: greenyellow;">sudo dd bs=4M if=gateway-0.3.0.img of=/dev/¿¿¿</span> <span style="color: red;"># substitute your device name</span><br />[sudo] password for lars: <span style="color: greenyellow;">**********</span><br /></span></tt></blockquote>Because my Raspberry Pi is headless, having no keyboard or monitor, I need to have a way to communicate with it if something goes wrong. I'm going to enable the ssh server so I can connect to it from another computer.<br /><blockquote style="background-color: black; color: #777777;"><tt><span style="font-family: monospace; font-size: small;">bozeman:~/Downloads ᚥ <span style="color: greenyellow;">mkdir rpi-boot</span><br />bozeman:~/Downloads ᚥ <span style="color: greenyellow;">sudo mount /dev/¿¿¿1 rpi-boot</span> <span style="color: red;"># substitute your device name</span><br />bozeman:~/Downloads ᚥ <span style="color: greenyellow;">sudo touch rpi-boot/ssh</span><br />bozeman:~/Downloads ᚥ <span style="color: greenyellow;">sudo umount rpi-boot</span><br />bozeman:~/Downloads ᚥ <span style="color: greenyellow;">rmdir rpi-boot</span><br />bozeman:~/Downloads ᚥ </span></tt></blockquote><br /><b>Step 3</b>: I put the newly minted µSD card, the X-Stick and the network cable into my Raspberry Pi and applied power. It took about 45 seconds to boot to the point that the ssh server was working. While I waited, I set up my two test lamps.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-EJOyhkn26MA/Wn8hia-a3cI/AAAAAAAApM4/i2lw0-WN2lgb3d5BPCSrNIxV0I6LPmXfQCLcBGAs/s1600/2018-02-09%2B16.16.55.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-EJOyhkn26MA/Wn8hia-a3cI/AAAAAAAApM4/i2lw0-WN2lgb3d5BPCSrNIxV0I6LPmXfQCLcBGAs/s320/2018-02-09%2B16.16.55.jpg" width="320" /></a></div><br /><br /><b>Step 4</b>: I'm going to depend on ssh to communicate with the Raspberry Pi, so I need to make sure ssh is secure. We can't let the "pi" account sit with the default password, so we must change it.<br /><blockquote style="background-color: black; color: #777777;"><tt><span style="font-family: monospace; font-size: small;">bozeman:~/Downloads ᚥ <span style="color: greenyellow;">ssh pi@gateway.local</span><br />pi@gateway.local's password: <span style="color: greenyellow;">raspberry</span><br />Linux gateway 4.9.59-v7+ #1047 SMP Sun Oct 29 12:19:23 GMT 2017 armv7l<br />...<br />pi@gateway:~ $ <span style="color: greenyellow;">passwd</span><br />Changing password for pi.<br />(current) UNIX password:<span style="color: greenyellow;">raspberry</span><br />Enter new UNIX password: <span style="color: greenyellow;">**********</span><br />Retype new UNIX password: <span style="color: greenyellow;">**********</span><br />passwd: password updated successfully<br />pi@gateway:~ $ <span style="color: greenyellow;">exit</span><br />logout<br />Connection to gateway.local closed.<br />bozeman:~/Downloads ᚥ <br /></span></tt></blockquote><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><b>Step 5</b>: By this time, the Thing Gateway web server was up and running and I connected to it with Firefox on my workstation.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-CUhAY9FlweM/Wn5HMo9mpXI/AAAAAAAApKs/_PUU6_AKWxgDaYjFewFbQtr9BCRsOIuhgCLcBGAs/s1600/001.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-CUhAY9FlweM/Wn5HMo9mpXI/AAAAAAAApKs/_PUU6_AKWxgDaYjFewFbQtr9BCRsOIuhgCLcBGAs/s320/001.png" width="229" /></a></div><br />I'd rather have my Gateway communicate over its Ethernet cable, so I don't want to setup WiFi. I pressed Skip.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-lPIjLRUW714/Wn5VVRNTXRI/AAAAAAAApK8/IVe94Pebtu4K36FbwLDaFQMm43gU3I6LACLcBGAs/s1600/002.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://1.bp.blogspot.com/-lPIjLRUW714/Wn5VVRNTXRI/AAAAAAAApK8/IVe94Pebtu4K36FbwLDaFQMm43gU3I6LACLcBGAs/s320/002.jpg" width="229" /></a></div><br />At this point in the setup, the Raspberry Pi is going to reboot. For me, it took about <b>two minutes</b> before I was able to move on.</div><br /><div style="text-align: left;"><b>Step 6</b>: After the delay, I retyped "gateway.local" into the URL bar to continue with the setup. In this step, one would normally choose a subdomain so that their Things Gateway would be accessible from the Internet. I do not intend to use that feature.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-hyRj-lVwmEQ/Wn5WQRO95yI/AAAAAAAApLE/dbvSfdQPuaUgEIpHzxrx-a9rXaWeluiHwCLcBGAs/s1600/003.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-hyRj-lVwmEQ/Wn5WQRO95yI/AAAAAAAApLE/dbvSfdQPuaUgEIpHzxrx-a9rXaWeluiHwCLcBGAs/s320/003.jpg" width="229" /></a></div><br />Again, I pressed Skip.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-wS4Zt2vz1WM/Wn5WgxRDccI/AAAAAAAApLI/0gAflQNfRUIJ9TFidANlHCStbdHYsE_-ACLcBGAs/s1600/004.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://3.bp.blogspot.com/-wS4Zt2vz1WM/Wn5WgxRDccI/AAAAAAAApLI/0gAflQNfRUIJ9TFidANlHCStbdHYsE_-ACLcBGAs/s320/004.jpg" width="229" /></a></div><br /></div><div style="text-align: left;"><br /><b>Step 6</b>: Next, it registers a username and password. I'll use this to login to the Things Gateway from my browser on my local network. Notice that the Firefox URL Bar shows that this Web Site is insecure. When you type your user name and password, you'll be warned again.<br /><br />Because we're on our own network, this a tolerable situation for the moment. We could add a self signed certificate and add a security exception to get rid of the warnings, but for now, I'm going to live with it.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-7yAaR2btKvM/Wn5XgLP-ATI/AAAAAAAApLU/q7OycBeOPl0eLAdrHjBM3VdAIe7ckDNngCLcBGAs/s1600/006.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://1.bp.blogspot.com/-7yAaR2btKvM/Wn5XgLP-ATI/AAAAAAAApLU/q7OycBeOPl0eLAdrHjBM3VdAIe7ckDNngCLcBGAs/s320/006.jpg" width="229" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><b>Step 7</b>: The Things Gateway is now up and running. It shows us that it has not detected any devices yet. However, before we move on, we can enable some more features in the Zigbee Adapter by updating it. The simplest way to do that is to delete the Add-on that controls it and immediately reinstalling it.<br /><br />Go to settings, by clicking the 3 horizontal bar drop-down menu icon in the upper left, selecting Settings, then Add-ons:<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-NkiB3sdJ1zg/Wn5ZkyUrdBI/AAAAAAAApLg/72winXcsSwoMd-P_FHKXgeKL3WBgRKj-ACLcBGAs/s1600/008.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://2.bp.blogspot.com/-NkiB3sdJ1zg/Wn5ZkyUrdBI/AAAAAAAApLg/72winXcsSwoMd-P_FHKXgeKL3WBgRKj-ACLcBGAs/s320/008.jpg" width="216" /></a></div><br />Remove the zigbee-adapter add-on:<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-7seS0yBmBeU/Wn5Z3ANPY8I/AAAAAAAApLk/LU20mENalTMCY-9dmKXey1LB7jm9ivKHgCLcBGAs/s1600/009.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://2.bp.blogspot.com/-7seS0yBmBeU/Wn5Z3ANPY8I/AAAAAAAApLk/LU20mENalTMCY-9dmKXey1LB7jm9ivKHgCLcBGAs/s320/009.jpg" width="229" /></a></div><br />Then Click the "+" and to add it back in. This ensures we've got the latest code. I think this is an awkward way to get an update, hopefully the project will improve that particular piece of UX.<br /><br /><b>Step 8</b>: Leave settings by backing out using the Left Arrow buttons in the upper left until you're back to the Main Menu:<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-vTy2Wxw0WlU/Wn5auwDkJJI/AAAAAAAApL8/KJXR9hTPwFkZgkWeEYooTRbOjH0gGZQnQCLcBGAs/s1600/016.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-vTy2Wxw0WlU/Wn5auwDkJJI/AAAAAAAApL8/KJXR9hTPwFkZgkWeEYooTRbOjH0gGZQnQCLcBGAs/s320/016.jpg" width="229" /></a></div><br />Select "Things" Then press the "+" button.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-TnD9gGlmYPM/Wn5bHczqK6I/AAAAAAAApMA/V0xEGEh-lIMXMjRPHi9ap_5vm3VnRXlmQCLcBGAs/s1600/017.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://2.bp.blogspot.com/-TnD9gGlmYPM/Wn5bHczqK6I/AAAAAAAApMA/V0xEGEh-lIMXMjRPHi9ap_5vm3VnRXlmQCLcBGAs/s320/017.jpg" width="229" /></a></div><br /><b>Step 9</b>: For me, it immediately found my two devices: the plug on/off switch and the CREE dimmable light bulb. I gave them more understandable names, pressed "Save" on each and then "Done".<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-IvQEt1PnZAI/Wn5bzEO9kOI/AAAAAAAApMQ/FuiYHcKN5FgWsnZb4zw5z6eckRbeuV0TgCLcBGAs/s1600/021.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-IvQEt1PnZAI/Wn5bzEO9kOI/AAAAAAAApMQ/FuiYHcKN5FgWsnZb4zw5z6eckRbeuV0TgCLcBGAs/s320/021.jpg" width="229" /></a></div><br /><b>Step 10</b>: Next I got to enjoy the ability to control lights from my computer for the the first time since the 1990s. I explored the interface, and made a few rules.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-LOlUCdi7W3A/Wn8iZsiq3OI/AAAAAAAApNA/TSZaVACF2_Y3K8RwR2nqOIt-jmKjouevQCLcBGAs/s1600/2018-02-09%2B16.17.29.jpg" style="float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="240" src="https://1.bp.blogspot.com/-LOlUCdi7W3A/Wn8iZsiq3OI/AAAAAAAApNA/TSZaVACF2_Y3K8RwR2nqOIt-jmKjouevQCLcBGAs/s320/2018-02-09%2B16.17.29.jpg" width="320" /></a><a href="https://2.bp.blogspot.com/-Y51yUhVZe-g/Wn8ihPExptI/AAAAAAAApNE/K93fkPdYsbUQF128OUwoSY3WMcgDJ035ACLcBGAs/s1600/2018-02-09%2B16.17.46.jpg" style="float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="240" src="https://2.bp.blogspot.com/-Y51yUhVZe-g/Wn8ihPExptI/AAAAAAAApNE/K93fkPdYsbUQF128OUwoSY3WMcgDJ035ACLcBGAs/s320/2018-02-09%2B16.17.46.jpg" width="320" /></a></div><br /><div class="separator" style="clear: both; text-align: left;">In future editions in this series, I'm going to setup lighting for an old fashioned photo darkroom. I want an easy way to switch between white and red safety lighting. So I'll make a rule that will not allow both red and white lights to be on at the same time. This sounds like a perfect use of Philips Hue color changing bulb, eh?</div><br />Why do we need lighting for a photo darkroom? I'll reveal that in a future blog post, too.<br /><br /><br /></div>Mon, 12 Feb 2018 21:27:36 +0000noreply@blogger.com (K Lars Lohn)Air Mozilla: Mozilla Weekly Project Meeting, 12 Feb 2018https://air.mozilla.org/mozilla-weekly-project-meeting-20180212/https://air.mozilla.org/mozilla-weekly-project-meeting-20180212/
<p>
<img alt="Mozilla Weekly Project Meeting" class="wp-post-image" height="90" src="https://air.cdn.mozilla.net/media/cache/e9/4f/e94fbd7f8df916c75a60e63a85b9168c.png" width="160" />
The Monday Project Meeting
</p>Mon, 12 Feb 2018 19:00:00 +0000Air MozillaDon Marti: FOSDEM videoshttps://blog.zgp.org/fosdem-videos/https://blog.zgp.org/fosdem-videos/
<p>Check it out. The
<a href="https://video.fosdem.org/2018/UA2.118%20%28Henriot%29/">videos from the Mozilla room at FOSDEM</a> are up,
and here's <a href="https://ftp.osuosl.org/pub/fosdem/2018/UA2.118%20%28Henriot%29/mozilla_bugmark.webm">me, talking about bug futures</a>.</p>
<p><a href="https://video.fosdem.org/">All FOSDEM videos</a></p>
<p>And, yes, the video link Just Works. Bonus link to some background on that: <a href="http://robert.ocallahan.org/2018/01/the-fight-for-patent-unencumbered-media.html">The Fight For Patent-Unencumbered Media Codecs Is Nearly Won</a> by Robert O'Callahan</p>
<p>Another bonus link: <a href="https://github.com/FOSDEM/video">FOSDEM video
project</a>,
including <a href="https://github.com/FOSDEM/video/tree/master/hardware">what those custom boxes
do</a>.</p>Sat, 10 Feb 2018 08:00:00 +0000Dzmitry Malyshau: Feasibility of low-level GPU access on the Webhttp://kvark.github.io/web/gpu/2018/02/10/low-level-gpu-web.htmlhttp://kvark.github.io/web/gpu/2018/02/10/low-level-gpu-web.html
<p>This is a follow up to <a href="http://kvark.github.io/web/3d/api/mozilla/2017/03/21/web-platform.html">Defining the Web platform</a> post from a year ago. It doesn’t try to answer questions but instead attempts to figure out what are the right questions to ask.</p>
<h3>Trade-offs</h3>
<p>As the talks within <a href="https://www.w3.org/community/gpu/">WebGPU</a> community group progress, it becomes apparent that the disagreements lie in more domains than simply technical. It’s about what the Web is today, and what we want it to become tomorrow. The further we go towards the rabbit hole of low-level features, the more we have to stretch the very definition of the Web:</p>
<ol>
<li>harder to guarantee security:
<ul>
<li>if the descriptors can be purely GPU driven (like Metal argument buffers), the browser can’t guarantee that they point to owned and initialized GPU memory.</li>
<li>if there are many exposed flags for device capabilities, it’s easy for a script to fingerprint users based on that profile.</li>
</ul>
</li>
<li>harder to achieve portability:
<ul>
<li>any use of incoherent memory</li>
<li>rich memory types spectrum (like Vulkan memory types/heaps) means that different platforms would have to take different code paths if implemented correctly, and that’s difficult to test</li>
</ul>
</li>
<li>makes the API increasingly more complex to use, which Web developers may not welcome:
<ul>
<li>declaring a Vulkan like render pass with multiple passes is a challenge</li>
</ul>
</li>
<li>finally, all this goes into performance characteristics:
<ul>
<li>potentially lower CPU cost, given the bulk of validation work moved from the driver onto the browser</li>
<li>more consistent framerate, given better control of scheduled GPU work</li>
</ul>
</li>
</ol>
<h3>Consistency</h3>
<p>It is clear that the native API have reached decent consistency in their respective programming models. Both Metal and Vulkan appear to be positioned at their local maximas, while I can’t confidently state the same about NXT that is unclear:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> /*| /**\ ?*?
/ | .. / \ ..... ? ? ?
Metal Vulkan NXT
</code></pre></div></div>
<p>One can’t just take a small step away from an existing API and remain consistent. Finding a whole new local maxima is hard because it means that the previous API designers (Khronos, Microsoft, Apple) either haven’t discovered it or simply discarded it for being inferior. And while we have Microsoft and Apple representatives in the group, we lack the opinion of Vulkan designers from Khronos.</p>
<h3>Origins</h3>
<p>My <a href="http://kvark.github.io/3d/api/2016/12/16/webmetal.html">first prototype</a> was based on Metal, after which I had a chance to talk a lot about the future of Web GPU access with fellow Mozillians. The feedback I got was very consistent:</p>
<ul>
<li>use existing Vulkan API, making necessary adjustments to provide security and portability</li>
<li>provide maximum <em>possible</em> performance by making a platform, let higher level libraries build on it and expose simpler APIs to the users</li>
</ul>
<p>A similar position was expressed by some of the <a href="https://www.khronos.org/blog/khronos-announces-the-vulkan-portability-initiative">Vulkan Portability</a> members. And this is where we’ve been going so far with the development of <a href="https://github.com/gfx-rs/portability">portability layer</a> and experiments with Vulkan-based WebIDL <a href="https://github.com/kvark/webgpu-servo">implementation in Servo</a>. Check out the <a href="https://www.youtube.com/watch?v=ApPJqWD9cDk">recent talk</a> at Fosdem 2018 as well as our <a href="http://gfx-rs.github.io/2017/12/30/this-year.html">2017 report</a> for more details. Unfortunately, this direction faces strong opposition from the rest of W3C group.</p>
<h3>Portability</h3>
<p>Interestingly, there is an existing precedent of providing a less portable Web platform API (quote from an <a href="https://hacks.mozilla.org/2017/06/avoiding-race-conditions-in-sharedarraybuffers-with-atomics/">article by Lin Clark</a>):</p>
<blockquote>
<p><code class="highlighter-rouge">SharedArrayBuffers</code> could result in race conditions. This makes working with <code class="highlighter-rouge">SharedArrayBuffers</code> hard. We don’t expect application developers to use <code class="highlighter-rouge">SharedArrayBuffers</code> directly.
But library developers who have experience with multithreaded programming in other languages can use these new low-level APIs to create higher-level tools. Then application developers can use these tools without touching <code class="highlighter-rouge">SharedArrayBuffers</code> or <code class="highlighter-rouge">Atomics</code> directly.</p>
</blockquote>
<p>So if the question is “Does Web API <em>have</em> to be portable?”, the answer is a definite “no”. It’s a nice property, but not a requirement, and can be justified by other factors, such as performance. Speaking of which… the case for performance gains in <code class="highlighter-rouge">SharedArrayBuffers</code> appears to be strong, which convinced the browser vendors to agree on exposing this low-level API. Now, can we apply the same reasoning to get Vulkan level of explicitness and portability to the Web? Can we rely on user libraries to make it more accessible and portable? Having some performance metrics would be great, but obtaining them appears to be extremely difficult.</p>
<p>Note: currently <code class="highlighter-rouge">SharedArrayBuffers</code> are disabled on all browsers due to the high-resolution timers in them discovered to be exploitable. One could argue that this is related to them being low-level, and thus we shouldn’t take them as a good example for a Web API. This is countered by the fact that the disabling is temporary, and the usefulness of SABs is completely clear (see <a href="https://github.com/tc39/security/issues/3">ECMA security issue</a>, also note this <a href="https://github.com/tc39/security/issues/3#issuecomment-364214608">comment</a>).</p>
<h3>Performance</h3>
<p>What would be a good benchmark that shows the cost of memory barriers and types being implicit in the API?</p>
<ol>
<li>we need to have the same GPU-intensive workloads running on Vulkan and Metal, preferably utilizing multiple command queues and advanced features like multiple passes or secondary command buffers</li>
<li>… on the same hardware, which means Windows installed on a MacBook. Even then, we may see the differences in how OS schedules hardware access, how drivers are implemented, how applications settings are configured on different OSes, etc.</li>
<li>the code paths split between Vulkan/Metal should be fairly high. If it’s done via an API abstraction layer like Vulkan Portability, then the results are obviously going to be skewed towards this API. Splitting at high level means taking most advantage of the native API features, but also means more work for the developer.</li>
</ol>
<p>Until that benchmarking is done, we can’t reasonably argue in favor of performance when there are concrete sacrifices in portability, API complexity (and security, to an extent) that come with it… Defending Vulkan-like approach goes like this:</p>
<ul>
<li><strong>A</strong>: pipeline barriers are confusing, error-prone, and not evidently fast, let’s make them implicit. Look, our native API does that, and it’s successful.</li>
<li><strong>M</strong>: but… tracking the actual layout and access flags on our side is hard (for the backends that require them), and it gets really difficult when multiple queues are involved that share resources</li>
<li><strong>G</strong>: let’s only share resources with immutable access flags then, and transition ownership explicitly between queues otherwise</li>
<li><strong>A</strong>: manually synchronizing submissions between queues is hard to get right anyway, prone to portability issues, etc. Let’s only have a single queue!</li>
</ul>
<p>And so it goes… one aspect leading to another, proving that the existing APIs are consistent and local maxima, and that Metal is technically easier to fit the shoes of the Web.</p>
<h3>Result</h3>
<p>Ok, this post is turning into a rant, rather inevitably… Sorry!</p>
<p>The unfortunate part of the story is that the group will not agree on an existing API, no matter what it is, because it would be biased towards a specific platform. And while Mozilla and Apple are at least conceptually aligned to existing API concepts, Google has been actively trying to come up with a new one in <a href="https://github.com/google/nxt-standalone">NXT</a>. As a result, not only the multi-platform applications would have to add support for yet another API when ported to the Web, that API is also going to be targeted from native via Emscripten and/or WebAssembly, and Google is all into providing the standalone (no-browser) way of using it, effectively <a href="https://xkcd.com/927/">adding to the list</a> of native APIs… Without any IHV backing, and promoted by… browser vendors? That is the path the group appears to be moving unconsciously in, instead of building on top of existing knowledge and research.</p>
<p>The current struggle of developing the Web GPU API comes down to many factors. One of the, if not the most, important ones here is that the parties have different end results envisioned. Some would like the JavaScript use to be nice, idiomatic, and error-resistant. Some mostly care about WebAssembly being fast. Some can’t afford a badly written application looking different on different mobile phones. Some can’t expect developers to be smart enough to use a complicated API. Some leave WebGL as a backup choice for a simple and accessible but slower API.</p>
<p>And the fact we are discussing this within W3C doesn’t help either. We don’t have immediate access to Khronos IHV experts and ISV advisory panels. We desperately need feedback from actual target users on what they want. Who knows, maybe the real answer is that we are better off without yet another API at all?</p>Sat, 10 Feb 2018 04:16:37 +0000The Mozilla Blog: An Open Letter to Justice Srikrishna About Data Privacy and Aadhaarhttps://blog.mozilla.org/?p=11238https://blog.mozilla.org/blog/2018/02/09/open-letter-justice-srikrishna-data-privacy-aadhaar/
<hr />
<p><i>Note: This open letter, penned by Mozilla executive chairwoman Mitchell Baker, appears as a <a href="http://paper.hindustantimes.com/epaper/iphone/homepage.aspx#_title1087201802090000005100100111/watitle1087201802090000005100100111/1087/10872018020900000051001001/11/true">full-page advertisement</a> in the February 9 edition of The Hindustan Times. It is co-signed by 1,447 Mozilla India community members. To learn more about Mozilla work regarding India’s data protection law and Aadhaar, visit </i><a href="https://foundation.mozilla.org/campaigns/aadhaar/"><i>https://foundation.mozilla.org/campaigns/aadhaar/</i></a><i>. </i></p>
<hr />
<p><img alt="" class="alignright size-medium wp-image-11241" height="479" src="https://blog.mozilla.org/wp-content/uploads/2018/02/DSC_3911-300x479.jpg" width="300" />Dear Justice Srikrishna and the Honourable Members of the Ministry of Electronics and Information Technology Committee of Experts,</p>
<p>With the support of and in solidarity with members of Mozilla’s community in India, I write today to urge you to stand up for the privacy and security of all Indians. Your recent consultation on the form of India’s first comprehensive data protection law comes at an auspicious time. The Supreme Court of India has ruled unequivocally that privacy is a fundamental right guaranteed to all Indians by the Indian Constitution. We ask that you take that decision and ensure that right is made a reality in law.</p>
<p>Mozilla’s work on upholding privacy is guided by the<a href="https://www.mozilla.org/en-US/about/manifesto/"> Mozilla Manifesto</a>, which states: “Individual security and privacy is fundamental and must not be treated as optional online” (Principle 4). Our commitment to the principle can be seen both in the open source code of our products as well as in our policies such as Mozilla’s<a href="https://www.mozilla.org/en%20-%20US/privacy/principles/"> Data Privacy Principles</a>. The Mozilla India Community has run<a href="https://wiki.mozilla.org/Privacy/Privacy_Task_Force/January_Campaign/2018"> numerous campaigns</a> to educate Indians on how to protect themselves online.</p>
<p>Data protection is a critical tool for guaranteeing fundamental rights of privacy. It is particular important today as Aadhaar is being driven deeper into all aspects of life. Digital identity can bring many benefits, but it can also become a surveillance and privacy disaster. A strong data protection law is key to avoiding disaster.</p>
<p>In the digital age, especially in regards to the Aadhaar, individual security and privacy is increasingly being put at risk. Recently, a private citizen was able to<a href="https://blog.mozilla.org/netpolicy/2018/01/04/mozilla-statement-breach-aadhaar-data/"> buy access to all of the demographic data in the Aadhaar database</a> for just 500 rupees. There have been countless leaks, security incidents, and<a href="https://timesofindia.indiatimes.com/india/210-govt-websites-made-public-aadhaar-details-uidai/articleshow/61711303.cms"> instances where private Aadhaar data has been published online</a>.<a href="https://blog.mozilla.org/netpolicy/2017/11/16/need-aadhaar-to-investigate-lost-package/"> Private companies are increasingly requiring Aadhaar</a> in order to use their services. In the vacuum created by India’s lack of a comprehensive data protection law, the Government of India continues its<a href="http://www.hindustantimes.com/interactives/aadhaar-mandatory-schemes-timeline/"> relentless push to make Aadhaar mandatory</a> for ever more government programs and private sector services, in contravention of the directives of the Supreme Court.</p>
<p>We commend you for the strong recommendations and overall framework proposed in your report. While this represents important progress in developing a strong data protection framework, we remain concerned about several missing protections:</p>
<ul>
<li>The current proposal exempts biometric info from the definition of sensitive personal information that must be especially protected. This is backwards, biometric info is some of the most personal info, and can’t be “reset’ like a password.</li>
<li>The design of Aadhaar fails to provide meaningful consent to users. This is seen, for example, by the ever increasing number of public and private services that are linked to Aadhaar without users being given a meaningful choice in the matter. This can and should be remedied by stronger consent, data minimization, collection limitation, and purpose limitation obligations.</li>
<li>Instead of crafting narrow exemptions for the legitimate needs of law enforcement, you propose to exempt entire agencies from accountability and legal restrictions on how user data may be accessed and processed.</li>
<li>Your report also casts doubt on whether individuals should be allowed a right to object over how their data is processed; this is a core pillar of data protection, without a right to object, consent is not meaningful and individual liberty is curtailed.</li>
</ul>
<p>There is resounding support for privacy in India, and the Supreme Court has made clear that the protection of individual privacy and security is an imperative for the Government of India. We hope you and your colleagues in the Government of India will take this opportunity to develop a data protection law that strongly protects the rights of users and makes India’s framework a model for the world.</p>
<p>Sincerely,</p>
<p>Mitchell Baker, Executive Chairwoman, Mozilla</p>
<hr />
<p><b>The Hindustan Times advertisement:</b></p>
<p><img alt="" class="aligncenter wp-image-11241 size-large" height="959" src="https://blog.mozilla.org/wp-content/uploads/2018/02/DSC_3911-600x959.jpg" width="600" /></p>
<p> </p>
<p>The post <a href="https://blog.mozilla.org/blog/2018/02/09/open-letter-justice-srikrishna-data-privacy-aadhaar/" rel="nofollow">An Open Letter to Justice Srikrishna About Data Privacy and Aadhaar</a> appeared first on <a href="https://blog.mozilla.org" rel="nofollow">The Mozilla Blog</a>.</p>Fri, 09 Feb 2018 14:34:05 +0000Mitchell BakerNick Fitzgerald: A Wee Allocator for WebAssemblyhttp://fitzgeraldnick.com/2018/02/09/wee-alloc.htmlhttp://fitzgeraldnick.com/2018/02/09/wee-alloc.html
<p><a href="https://hacks.mozilla.org/2018/01/oxidizing-source-maps-with-rust-and-webassembly/">Recently, we introduced WebAssembly (compiled from Rust) into the <code>source-map</code> JavaScript library.</a>
We saw parsing and querying source maps get a whole lot faster. But keeping the
compiled <code>.wasm</code> code size small was a challenge.</p>
<p>There are a variety of tools available for removing dead code from WebAssembly
and compressing <code>.wasm</code> sizes:</p>
<ul>
<li>
<p><a href="https://github.com/alexcrichton/wasm-gc"><code>wasm-gc</code></a> constructs the callgraph of all the functions in a
<code>.wasm</code> file, determines which functions are never transitively called by an
exported function, and removes them.<sup id="back-foot-0"><a href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#foot-0">0</a></sup></p>
</li>
<li>
<p><a href="https://github.com/fitzgen/wasm-snip"><code>wasm-snip</code></a> replaces a WebAssembly function’s body with a single
<code>unreachable</code> instruction. This is useful for manually removing functions that
will never be called at runtime, but which the compiler and <code>wasm-gc</code> couldn’t
statically prove were dead. After snipping a function, other functions that
were only called by the snipped function become unreachable, so running
<code>wasm-gc</code> again after <code>wasm-snip</code> often yields further code size reductions.</p>
</li>
<li>
<p><code>wasm-opt</code> runs <a href="https://github.com/WebAssembly/binaryen"><code>binaryen</code>‘s</a> sophisticated optimization passes
over a <code>.wasm</code> file, both shrinking its size and improving its runtime
performance.</p>
</li>
</ul>
<p>After using these tools, we looked at what was left in our <code>.wasm</code> file, and
broke the results down by crate:</p>
<p><a href="http://fitzgeraldnick.com/media/source-maps-rust-and-wasm/crate-size.svg" title="Code Size by Crate"></a></p>
<p>Half of our code size was coming from <code>dlmalloc</code>, the allocator that Rust uses
by default for the <code>wasm32-unknown-unknown</code> target. Source map parsing requires
just a couple of large, long-lived allocations, and then does its heavy lifting
without allocating any further. Querying a parsed source map doesn’t require
<em>any</em> allocation. So we are paying a lot, in code size, for an allocator that we
aren’t really using that much.</p>
<p>Allocator implementations have trade offs, but Rust’s default is the wrong
choice for the source map parsing and querying scenario.</p>
<h3>Introducing <code>wee_alloc</code></h3>
<p><a href="https://github.com/fitzgen/wee_alloc"><code>wee_alloc</code></a> is a work-in-progress memory allocator designed for
WebAssembly. It has a tiny code size footprint, compiling down to only a
kilobyte of <code>.wasm</code> code.</p>
<p><code>wee_alloc</code> is designed for scenarios like those described above: where there
are a handful of initial, long-lived allocations, after which the code does its
heavy lifting without any further allocations. This scenario requires <em>some</em>
allocator to exist, but we are more than happy to trade performance for small
code size.</p>
<p>In contrast, <code>wee_alloc</code> is not designed for, and would be a poor choice in,
scenarios where allocation is a performance bottleneck.</p>
<p>Although WebAssembly is the primary target, <code>wee_alloc</code> also has an <code>mmap</code>-based
implementation for unix systems. This enables testing <code>wee_alloc</code>, and using
<code>wee_alloc</code> in your own code, without a browser or WebAssembly engine.</p>
<h3>How <code>wee_alloc</code> Works</h3>
<h4>Allocating WebAssembly Pages</h4>
<p>WebAssembly module instances have a linear memory space<sup id="back-foot-1"><a href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#foot-1">1</a></sup>, and use store and load
<a href="https://webassembly.github.io/spec/core/syntax/instructions.html#memory-instructions">instructions</a> to access values within it via an index. If an
instruction attempts to access the value at an index that is beyond the memory’s
bounds, a trap is raised.</p>
<p>There are two instructions for manipulating the linear memory space itself,
rather than its contents: <code>current_memory</code> and <code>grow_memory</code><sup id="back-foot-2"><a href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#foot-2">2</a></sup>. The <code>current_memory</code> instruction gives the
current size of memory, in units of pages. The <code>grow_memory</code> instruction takes
an operand <em>n</em>, grows the memory space by <em>n</em> pages, and gives back the <em>old</em>
size of memory, units of pages. Alternatively, if growing memory fails, <code>-1</code> is
returned.</p>
<p>WebAssembly does not have any facilities for shrinking memory, at least right
now.</p>
<p>To implement allocating <em>n</em> pages of memory to Rust, we need to use LLVM’s
intrinsics. Right now, the intrinsic for <code>grow_memory</code> doesn’t expose the return
value, but this should be fixed once Rust updates its LLVM. Therefore, our page
allocation routine must use <code>current_memory</code> before <code>grow_memory</code>, when it
<em>should</em> just use the result of <code>grow_memory</code> instead. It also means we can’t
check for failure yet.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">extern</span> <span class="s">"C"</span> <span class="p">{</span>
<span class="cp">#[link_name = </span><span class="s">"llvm.wasm.current.memory.i32"</span><span class="cp">]</span>
<span class="k">fn</span> <span class="n">current_memory</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">usize</span><span class="p">;</span>
<span class="cp">#[link_name = </span><span class="s">"llvm.wasm.grow.memory.i32"</span><span class="cp">]</span>
<span class="k">fn</span> <span class="n">grow_memory</span><span class="p">(</span><span class="n">pages</span><span class="o">:</span> <span class="n">usize</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">unsafe</span> <span class="k">fn</span> <span class="n">get_base_pointer</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="o">*</span><span class="k">mut</span> <span class="kt">u8</span> <span class="p">{</span>
<span class="p">(</span><span class="n">current_memory</span><span class="p">()</span> <span class="o">*</span> <span class="n">PAGE_SIZE</span><span class="p">.</span><span class="mi">0</span><span class="p">)</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="kt">u8</span>
<span class="p">}</span>
<span class="k">unsafe</span> <span class="k">fn</span> <span class="n">alloc_pages</span><span class="p">(</span><span class="n">n</span><span class="o">:</span> <span class="n">Pages</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="o">*</span><span class="k">mut</span> <span class="kt">u8</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">ptr</span> <span class="o">=</span> <span class="n">get_base_pointer</span><span class="p">();</span>
<span class="n">grow_memory</span><span class="p">(</span><span class="n">n</span><span class="p">.</span><span class="mi">0</span><span class="p">);</span>
<span class="n">ptr</span>
<span class="p">}</span></code></pre></figure>
<p>Careful readers will have noticed the <code>Pages</code> type in <code>alloc_pages</code>’s type
signature. <code>wee_alloc</code> uses newtypes for units of bytes, words, and pages. Each
of these is a thin wrapper around a <code>usize</code> with relevant operator overloads and
inter-conversions. This has been very helpful in catching bugs at compile time,
like attempts to offset a pointer by two words rather than two bytes, and
compiles away to nothing in the emitted <code>.wasm</code>.</p>
<h4>Free Lists</h4>
<p>But we don’t satisfy individual allocation requests by directly allocating
pages. First, the WebAssembly page size is 64KiB, which is much larger than most
allocations. Second, because there is no way to return unused pages to the
WebAssembly engine, it would be incredibly wasteful if we didn’t reuse
pages. Instead, we maintain a free list of blocks of memory we’ve already
allocated from the WebAssembly engine.</p>
<p>Free lists have low complexity and are easy to implement. These properties also
lend themselves to a <em>small</em> implementation. The basic idea is to maintain an
intrusive linked list of memory blocks that are available. Allocation removes a
block from the free list. If the block is larger than the requested allocation
size, we can split it in two. Or, if there is no suitable block available in the
free list, we can fall back to <code>alloc_pages</code> to get a fresh block of
memory. Deallocation reinserts the given block back into the free list, so that
it can be reused for future allocations. Because a block is only in the free
list if it is not allocated and is therefore unused, we can use a word from the
data itself to store the free list links, so long as we ensure that the data is
always at least a word in size.</p>
<p>Here is a diagram of what the free list looks like in memory, showing a free
block, followed by an allocated block, followed by another free block:</p>
<pre class="diagram"><code>
--. .--------------------------------------. ,-----------
| | | |
V | V |
+----------------\\-----+---------\\-----+---------------
| free ; data... // ... | data... // ... | free ; data...
+----------------\\-----+---------\\-----+---------------
</code></pre>
<p>Even after choosing to use free lists, we have more design choices to make. How
should we choose which block to use from the free list? The first that can
satisfy this allocation, aka <em>first fit</em>? The block that is closest to the
requested allocation size, in an effort to cut down on fragmentation (more on
this in a minute), aka <em>best fit</em>? Pick up the search where we left off last
time, aka <em>next fit</em>? Regardless which of first fit, best fit, and next fit we
choose, we are dealing with an <em>O(n)</em> search. Indeed, this is the downside to
the trade off we made when choosing free lists for their simplicity of
implementation.</p>
<p>A common technique for speeding up free list allocation is to have separate free
lists for allocations of different sizes, which is known as <em>segregated fits</em> or
having <em>size classes</em>. With this approach, we can guarantee the invariant that
every block in the free list for a particular size can satisfy an allocation
request of that size. All we need to do is avoid splitting any block into pieces
smaller than that size.</p>
<p>Maintaining this invariant gives us amortized <em>O(1)</em> allocation for these sizes
with their own free lists. Using first fit within a size’s free list is
guaranteed to only look at the first block within the free list, because the
invariant tells us that the first block can satisfy this request. It is
amortized because we need to fall back to the <em>O(n)</em> allocation to refill this
size’s free list from the fallback, main free list whenever it is empty.</p>
<p><strong>If we reuse the same first fit allocation routine for both our size classes’
free lists and our main free list, then we get the benefits of size classes
without paying for them in extra code size.</strong></p>
<p>This is the approach that <code>wee_alloc</code> takes.</p>
<h4>Fragmentation</h4>
<p>Our other main concern is avoiding <a href="https://en.wikipedia.org/wiki/Fragmentation_(computing)">fragmentation</a>. Fragmentation is the degree
of wasted space between allocations in memory. High fragmentation can lead to
situations where there exist many free blocks of memory, but none of which can
fulfill some allocation request, because each individual free block’s size is
too small, even if the sum of their sizes is more than enough for the requested
allocation. Therefore, a high degree of fragmentation can effectively break an
allocator. It had one job — allocate memory — and it can’t even do
that anymore. So <code>wee_alloc</code> really should have <em>some</em> kind of story here;
punting 100% on fragmentation is not a practical option.</p>
<p>Once again there are trade offs, and avoiding fragmentation is not a binary
choice. On one end of the spectrum, compacting garbage collectors can re-arrange
objects in memory and pack them tightly next to each other, effectively leading
to zero fragmentation. The cost that you pay is the size and time overhead of a
full tracing garbage collector that can enumerate all pointers in the system and
patch them to point to moved objects’ new locations. On the opposite end of the
spectrum, if we never re-consolidate two blocks of adjacent memory that we
previously split from what had originally been a single contiguous block, then
we can expect a lot of fragmentation. As we split blocks into smaller blocks for
smaller allocations, we get small bits of wasted space between them, and even
after we free all these small allocations, we won’t have any large block in the
free list for a large allocation. Even if we have multiple adjacent, small
blocks in the free list that could be merged together to satisfy the large
allocation.</p>
<p>One possibility is keeping the free list sorted by each block’s address, and
then deallocating a block would re-insert it into the free list at the sorted
location. If either of its neighbors in the free list are immediately adjacent
in memory, we could consolidate them. But then deallocation is an <em>O(n)</em> search
through the free list, instead of the <em>O(1)</em> push onto its front. We could lower
that to <em>O(log n)</em> by representing the free list as a balanced search tree or
btree. But the implementation complexity goes up, and I suspect code size will
go up with it.</p>
<p>Instead of a free list, we could use bitmaps to track which portions of our heap
are free or allocated, and then the consolidation could happen automatically as
bits next to each other are reset. But then we need to restrict our allocator to
parceling out portions of a single, contiguous region of memory. This implies
that only a single, global allocator exists, since if there were multiple, each
instance would want to “own” the end of the WebAssembly linear memory, and have
the power to grow it to satisfy more and larger allocations. And maybe this is a
fair constraint to impose in the context of WebAssembly, where memory is already
linear and contiguous. But lifting this constraint, while still using bitmaps,
implies a hybrid free list and bitmap implementation. The downside to that is
more implementation complexity, and a larger code size foot print.</p>
<p><code>wee_alloc</code> takes a third approach: trading some space overhead for easy and
fast merging. We maintain a sorted, doubly-linked list of all blocks, whether
allocated or free. This adds two words of space overhead to every heap
allocation. When freeing a block, we check if either of its adjacent blocks are
also free, and if so, merge them together with a handful of updates to the next
and previous pointers. If neither of the neighbors are free, then we push this
block onto the front of the free list. In this way, we keep both <em>O(1)</em>
deallocation and our simple free list implementation.</p>
<p>Here is a diagram of what this sorted, doubly-linked list looks like in memory:</p>
<pre class="diagram"><code>
,---------------------------------. ,---------------------
| ,--|---------------------------|--.
| X | | | |
V | V | V |
+-----------------------\\-----+-----------------------\\-----+----------------------
| prev ; next ; data... // ... | prev ; next ; data... // ... | prev ; next ; data...
+-----------------------\\-----+-----------------------\\-----+----------------------
| ^ | ^ |
| | | | |
`---------------------' `---------------------' `------------
</code></pre>
<h4><code>CellHeader</code>, <code>FreeCell</code>, and <code>AllocatedCell</code></h4>
<p>The <code>CellHeader</code> contains the common data members found within both allocated
and free memory blocks: the next and previous doubly-linked list pointers.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="cp">#[repr(C)]</span>
<span class="k">struct</span> <span class="n">CellHeader</span> <span class="p">{</span>
<span class="n">next_cell_raw</span><span class="o">:</span> <span class="n">ptr</span><span class="o">::</span><span class="n">NonNull</span><span class="o">&lt;</span><span class="n">CellHeader</span><span class="o">&gt;</span><span class="p">,</span>
<span class="n">prev_cell_raw</span><span class="o">:</span> <span class="o">*</span><span class="k">mut</span> <span class="n">CellHeader</span><span class="p">,</span>
<span class="p">}</span></code></pre></figure>
<p>We use a low bit of the <code>next_cell_raw</code> pointer to distinguish whether the cell
is allocated or free, and can consult its value to dynamically cast to an
<code>AllocatedCell</code> or <code>FreeCell</code>.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">impl</span> <span class="n">CellHeader</span> <span class="p">{</span>
<span class="kr">const</span> <span class="n">IS_ALLOCATED</span><span class="o">:</span> <span class="n">usize</span> <span class="o">=</span> <span class="mb">0b01</span><span class="p">;</span>
<span class="k">fn</span> <span class="n">is_allocated</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">bool</span> <span class="p">{</span>
<span class="bp">self</span><span class="p">.</span><span class="n">next_cell_raw</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">()</span> <span class="k">as</span> <span class="n">usize</span> <span class="o">&amp;</span> <span class="n">Self</span><span class="o">::</span><span class="n">IS_ALLOCATED</span> <span class="o">!=</span> <span class="mi">0</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="n">is_free</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">bool</span> <span class="p">{</span>
<span class="o">!</span><span class="bp">self</span><span class="p">.</span><span class="n">is_allocated</span><span class="p">()</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="n">set_allocated</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">next</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">next_cell_raw</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">()</span> <span class="k">as</span> <span class="n">usize</span><span class="p">;</span>
<span class="kd">let</span> <span class="n">next</span> <span class="o">=</span> <span class="n">next</span> <span class="o">|</span> <span class="n">Self</span><span class="o">::</span><span class="n">IS_ALLOCATED</span><span class="p">;</span>
<span class="bp">self</span><span class="p">.</span><span class="n">next_cell_raw</span> <span class="o">=</span> <span class="k">unsafe</span> <span class="p">{</span>
<span class="n">ptr</span><span class="o">::</span><span class="n">NonNull</span><span class="o">::</span><span class="n">new_unchecked</span><span class="p">(</span><span class="n">next</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="n">CellHeader</span><span class="p">)</span>
<span class="p">};</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="n">set_free</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">next</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">next_cell_raw</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">()</span> <span class="k">as</span> <span class="n">usize</span><span class="p">;</span>
<span class="kd">let</span> <span class="n">next</span> <span class="o">=</span> <span class="n">next</span> <span class="o">&amp;</span> <span class="o">!</span><span class="n">Self</span><span class="o">::</span><span class="n">IS_ALLOCATED</span><span class="p">;</span>
<span class="bp">self</span><span class="p">.</span><span class="n">next_cell_raw</span> <span class="o">=</span> <span class="k">unsafe</span> <span class="p">{</span>
<span class="n">ptr</span><span class="o">::</span><span class="n">NonNull</span><span class="o">::</span><span class="n">new_unchecked</span><span class="p">(</span><span class="n">next</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="n">CellHeader</span><span class="p">)</span>
<span class="p">};</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="n">as_free_cell_mut</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="o">&gt;</span> <span class="p">{</span>
<span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">is_free</span><span class="p">()</span> <span class="p">{</span>
<span class="nb">Some</span><span class="p">(</span><span class="k">unsafe</span> <span class="p">{</span> <span class="n">mem</span><span class="o">::</span><span class="n">transmute</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="p">})</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nb">None</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>We use pointer arithmetic to calculate the size of a given cell’s data to avoid
another word of space overhead, so the <code>next_cell_raw</code> pointer must always point
just <em>after</em> this cell’s data. But, because of that restriction, we can’t use a
null pointer as the sentinel for the end of the doubly-linked-list. Therefore,
we use the second low bit of the <code>next_cell_raw</code> pointer to distinguish whether
the data pointed to by <code>next_cell_raw</code> (after the appropriate masking) is a
valid cell, or is garbage memory.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">impl</span> <span class="n">CellHeader</span> <span class="p">{</span>
<span class="kr">const</span> <span class="n">NEXT_CELL_IS_INVALID</span><span class="o">:</span> <span class="n">usize</span> <span class="o">=</span> <span class="mb">0b10</span><span class="p">;</span>
<span class="kr">const</span> <span class="n">MASK</span><span class="o">:</span> <span class="n">usize</span> <span class="o">=</span> <span class="o">!</span><span class="mb">0b11</span><span class="p">;</span>
<span class="k">fn</span> <span class="n">next_cell_is_invalid</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">bool</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">next</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">next_cell_raw</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">()</span> <span class="k">as</span> <span class="n">usize</span><span class="p">;</span>
<span class="n">next</span> <span class="o">&amp;</span> <span class="n">Self</span><span class="o">::</span><span class="n">NEXT_CELL_IS_INVALID</span> <span class="o">!=</span> <span class="mi">0</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="n">next_cell_unchecked</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="o">*</span><span class="k">mut</span> <span class="n">CellHeader</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">ptr</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">next_cell_raw</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">()</span> <span class="k">as</span> <span class="n">usize</span><span class="p">;</span>
<span class="kd">let</span> <span class="n">ptr</span> <span class="o">=</span> <span class="n">ptr</span> <span class="o">&amp;</span> <span class="n">Self</span><span class="o">::</span><span class="n">MASK</span><span class="p">;</span>
<span class="kd">let</span> <span class="n">ptr</span> <span class="o">=</span> <span class="n">ptr</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="n">CellHeader</span><span class="p">;</span>
<span class="n">ptr</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="n">next_cell</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;*</span><span class="k">mut</span> <span class="n">CellHeader</span><span class="o">&gt;</span> <span class="p">{</span>
<span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">next_cell_is_invalid</span><span class="p">()</span> <span class="p">{</span>
<span class="nb">None</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nb">Some</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">next_cell_unchecked</span><span class="p">())</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="n">size</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Bytes</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">data</span> <span class="o">=</span> <span class="k">unsafe</span> <span class="p">{</span> <span class="p">(</span><span class="bp">self</span> <span class="k">as</span> <span class="o">*</span><span class="kr">const</span> <span class="n">CellHeader</span><span class="p">).</span><span class="n">offset</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">};</span>
<span class="kd">let</span> <span class="n">data</span> <span class="o">=</span> <span class="n">data</span> <span class="k">as</span> <span class="n">usize</span><span class="p">;</span>
<span class="kd">let</span> <span class="n">next</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">next_cell_unchecked</span><span class="p">();</span>
<span class="kd">let</span> <span class="n">next</span> <span class="o">=</span> <span class="n">next</span> <span class="k">as</span> <span class="n">usize</span><span class="p">;</span>
<span class="n">Bytes</span><span class="p">(</span><span class="n">next</span> <span class="o">-</span> <span class="n">data</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>An <code>AllocatedCell</code> is a <code>CellHeader</code> followed by data that is allocated.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="cp">#[repr(C)]</span>
<span class="k">struct</span> <span class="n">AllocatedCell</span> <span class="p">{</span>
<span class="n">header</span><span class="o">:</span> <span class="n">CellHeader</span><span class="p">,</span>
<span class="p">}</span></code></pre></figure>
<p>A <code>FreeCell</code> is a <code>CellHeader</code> followed by data that is not in use, and from
which we recycle a word for the next link in the free list.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="cp">#[repr(C)]</span>
<span class="k">struct</span> <span class="n">FreeCell</span> <span class="p">{</span>
<span class="n">header</span><span class="o">:</span> <span class="n">CellHeader</span><span class="p">,</span>
<span class="n">next_free_raw</span><span class="o">:</span> <span class="o">*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="p">,</span>
<span class="p">}</span></code></pre></figure>
<p>Each of <code>AllocatedCell</code> and <code>FreeCell</code> have methods that make sense only when
the cell is allocated or free, respectively, and maintain the invariants
required for cells of their state. For example, the method for transforming a
<code>FreeCell</code> into an <code>AllocatedCell</code> ensures that the <code>IS_ALLOCATED</code> bit gets set,
and the method for transforming an <code>AllocatedCell</code> into a <code>FreeCell</code> unsets that
bit.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">impl</span> <span class="n">FreeCell</span> <span class="p">{</span>
<span class="k">unsafe</span> <span class="k">fn</span> <span class="n">into_allocated_cell</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">AllocatedCell</span> <span class="p">{</span>
<span class="bp">self</span><span class="p">.</span><span class="n">header</span><span class="p">.</span><span class="n">set_allocated</span><span class="p">();</span>
<span class="n">mem</span><span class="o">::</span><span class="n">transmute</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">impl</span> <span class="n">AllocatedCell</span> <span class="p">{</span>
<span class="k">unsafe</span> <span class="k">fn</span> <span class="n">into_free_cell</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">FreeCell</span> <span class="p">{</span>
<span class="bp">self</span><span class="p">.</span><span class="n">header</span><span class="p">.</span><span class="n">set_free</span><span class="p">();</span>
<span class="n">mem</span><span class="o">::</span><span class="n">transmute</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<h4>Implementing Allocation</h4>
<p>Let’s begin by looking at first fit allocation without any refilling of the free
list in the case where there are no available blocks of memory that can satisfy
this allocation request. Given the head of a free list, we search for the first
block that can fit the requested allocation. Upon finding a suitable block, we
determine whether to split the block in two, or use it as is. If we don’t find a
suitable block we return an error.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">unsafe</span> <span class="k">fn</span> <span class="n">walk_free_list</span><span class="o">&lt;</span><span class="n">F</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span><span class="p">(</span>
<span class="n">head</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="p">,</span>
<span class="k">mut</span> <span class="n">callback</span><span class="o">:</span> <span class="n">F</span><span class="p">,</span>
<span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="p">()</span><span class="o">&gt;</span>
<span class="n">where</span>
<span class="n">F</span><span class="o">:</span> <span class="n">FnMut</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="p">,</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">,</span>
<span class="p">{</span>
<span class="kd">let</span> <span class="k">mut</span> <span class="n">previous_free</span> <span class="o">=</span> <span class="n">head</span><span class="p">;</span>
<span class="k">loop</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">current_free</span> <span class="o">=</span> <span class="o">*</span><span class="n">previous_free</span><span class="p">;</span>
<span class="k">if</span> <span class="n">current_free</span><span class="p">.</span><span class="n">is_null</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">Err</span><span class="p">(());</span>
<span class="p">}</span>
<span class="kd">let</span> <span class="k">mut</span> <span class="n">current_free</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="n">current_free</span><span class="p">;</span>
<span class="k">if</span> <span class="kd">let</span> <span class="nb">Some</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="o">=</span> <span class="n">callback</span><span class="p">(</span><span class="n">previous_free</span><span class="p">,</span> <span class="n">current_free</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">Ok</span><span class="p">(</span><span class="n">result</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">previous_free</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">current_free</span><span class="p">.</span><span class="n">next_free_raw</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">unsafe</span> <span class="k">fn</span> <span class="n">alloc_first_fit</span><span class="p">(</span>
<span class="n">size</span><span class="o">:</span> <span class="n">Words</span><span class="p">,</span>
<span class="n">head</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="p">,</span>
<span class="n">policy</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">AllocPolicy</span><span class="p">,</span>
<span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Result</span><span class="o">&lt;*</span><span class="k">mut</span> <span class="kt">u8</span><span class="p">,</span> <span class="p">()</span><span class="o">&gt;</span> <span class="p">{</span>
<span class="n">walk_free_list</span><span class="p">(</span><span class="n">head</span><span class="p">,</span> <span class="o">|</span><span class="n">previous</span><span class="p">,</span> <span class="n">current</span><span class="o">|</span> <span class="p">{</span>
<span class="c1">// Check whether this cell is large enough to satisfy this allocation.</span>
<span class="k">if</span> <span class="n">current</span><span class="p">.</span><span class="n">header</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">.</span><span class="n">into</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">None</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// The cell is large enough for this allocation -- maybe *too*</span>
<span class="c1">// large. Try splitting it.</span>
<span class="k">if</span> <span class="kd">let</span> <span class="nb">Some</span><span class="p">(</span><span class="n">allocated</span><span class="p">)</span> <span class="o">=</span> <span class="n">current</span><span class="p">.</span><span class="n">split_alloc</span><span class="p">(</span><span class="n">previous</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">policy</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">Some</span><span class="p">(</span><span class="n">allocated</span><span class="p">.</span><span class="n">data</span><span class="p">());</span>
<span class="p">}</span>
<span class="c1">// This cell has crazy Goldilocks levels of "just right". Use it as is,</span>
<span class="c1">// without any splitting.</span>
<span class="o">*</span><span class="n">previous</span> <span class="o">=</span> <span class="n">current</span><span class="p">.</span><span class="n">next_free</span><span class="p">();</span>
<span class="kd">let</span> <span class="n">allocated</span> <span class="o">=</span> <span class="n">current</span><span class="p">.</span><span class="n">into_allocated_cell</span><span class="p">(</span><span class="n">policy</span><span class="p">);</span>
<span class="nb">Some</span><span class="p">(</span><span class="n">allocated</span><span class="p">.</span><span class="n">data</span><span class="p">())</span>
<span class="p">})</span>
<span class="p">}</span></code></pre></figure>
<p>Splitting a cell in two occurs when a cell has room for both the requested
allocation and for another adjacent cell afterwards that is no smaller than some
minimum block size. We use the <code>&amp;AllocPolicy</code> trait object to configure this
minimum block size, among other things, for different size classes without the
code duplication that monomorphization creates. If there is room to split, then
we insert the newly split cell into the free list, remove the current cell, and
fixup the doubly-linked list of adjacent cells in the headers.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">impl</span> <span class="n">FreeCell</span> <span class="p">{</span>
<span class="k">fn</span> <span class="n">should_split_for</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span> <span class="n">alloc_size</span><span class="o">:</span> <span class="n">Words</span><span class="p">,</span> <span class="n">policy</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">AllocPolicy</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">bool</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">self_size</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">header</span><span class="p">.</span><span class="n">size</span><span class="p">();</span>
<span class="kd">let</span> <span class="n">min_cell_size</span><span class="o">:</span> <span class="n">Bytes</span> <span class="o">=</span> <span class="n">policy</span><span class="p">.</span><span class="n">min_cell_size</span><span class="p">(</span><span class="n">alloc_size</span><span class="p">).</span><span class="n">into</span><span class="p">();</span>
<span class="kd">let</span> <span class="n">alloc_size</span><span class="o">:</span> <span class="n">Bytes</span> <span class="o">=</span> <span class="n">alloc_size</span><span class="p">.</span><span class="n">into</span><span class="p">();</span>
<span class="n">self_size</span> <span class="o">-</span> <span class="n">alloc_size</span> <span class="o">&gt;=</span> <span class="n">min_cell_size</span> <span class="o">+</span> <span class="n">size_of</span><span class="o">::&lt;</span><span class="n">CellHeader</span><span class="o">&gt;</span><span class="p">()</span>
<span class="p">}</span>
<span class="k">unsafe</span> <span class="k">fn</span> <span class="n">split_alloc</span><span class="p">(</span>
<span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">,</span>
<span class="n">previous</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="p">,</span>
<span class="n">alloc_size</span><span class="o">:</span> <span class="n">Words</span><span class="p">,</span>
<span class="n">policy</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">AllocPolicy</span><span class="p">,</span>
<span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="k">mut</span> <span class="n">AllocatedCell</span><span class="o">&gt;</span> <span class="p">{</span>
<span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">should_split_for</span><span class="p">(</span><span class="n">alloc_size</span><span class="p">,</span> <span class="n">policy</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">alloc_size</span><span class="o">:</span> <span class="n">Bytes</span> <span class="o">=</span> <span class="n">alloc_size</span><span class="p">.</span><span class="n">into</span><span class="p">();</span>
<span class="kd">let</span> <span class="n">remainder</span> <span class="o">=</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">data</span> <span class="o">=</span> <span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">.</span><span class="n">header</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="n">CellHeader</span><span class="p">).</span><span class="n">offset</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="kt">u8</span><span class="p">;</span>
<span class="n">data</span><span class="p">.</span><span class="n">offset</span><span class="p">(</span><span class="n">alloc_size</span><span class="p">.</span><span class="mi">0</span> <span class="k">as</span> <span class="n">isize</span><span class="p">)</span>
<span class="p">};</span>
<span class="kd">let</span> <span class="n">remainder</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="n">FreeCell</span><span class="o">::</span><span class="n">from_uninitialized</span><span class="p">(</span>
<span class="n">remainder</span><span class="p">,</span>
<span class="bp">self</span><span class="p">.</span><span class="n">header</span><span class="p">.</span><span class="n">next_cell_raw</span><span class="p">,</span>
<span class="nb">Some</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">.</span><span class="n">header</span><span class="p">),</span>
<span class="nb">Some</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">next_free</span><span class="p">()),</span>
<span class="n">policy</span><span class="p">,</span>
<span class="p">);</span>
<span class="k">if</span> <span class="kd">let</span> <span class="nb">Some</span><span class="p">(</span><span class="n">next</span><span class="p">)</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">header</span><span class="p">.</span><span class="n">next_cell</span><span class="p">()</span> <span class="p">{</span>
<span class="p">(</span><span class="o">*</span><span class="n">next</span><span class="p">).</span><span class="n">prev_cell_raw</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">remainder</span><span class="p">.</span><span class="n">header</span><span class="p">;</span>
<span class="p">}</span>
<span class="bp">self</span><span class="p">.</span><span class="n">header</span><span class="p">.</span><span class="n">next_cell_raw</span> <span class="o">=</span>
<span class="n">ptr</span><span class="o">::</span><span class="n">NonNull</span><span class="o">::</span><span class="n">new_unchecked</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">remainder</span><span class="p">.</span><span class="n">header</span><span class="p">);</span>
<span class="o">*</span><span class="n">previous</span> <span class="o">=</span> <span class="n">remainder</span><span class="p">;</span>
<span class="nb">Some</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">into_allocated_cell</span><span class="p">(</span><span class="n">policy</span><span class="p">))</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nb">None</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>Refilling a free list when there is not a suitable block already in it is
easy. For the main free list, we allocate new pages directly from the
WebAssembly engine with the <code>alloc_pages</code> function we defined earlier. For a
size class’s free list, we allocate a (relatively) large block from the main
free list. This logic is encapsulated in the two different <code>AllocPolicy</code>
implementations, and the <code>AllocPolicy::new_cell_for_free_list</code> method.</p>
<p>To allocate with a fallback to refill the free list, we do just that: attempt a
first fit allocation, if that fails, refill the free list by pushing a new cell
onto its front, and then try a first fit allocation once again.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">unsafe</span> <span class="k">fn</span> <span class="n">alloc_with_refill</span><span class="p">(</span>
<span class="n">size</span><span class="o">:</span> <span class="n">Words</span><span class="p">,</span>
<span class="n">head</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="p">,</span>
<span class="n">policy</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">AllocPolicy</span><span class="p">,</span>
<span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Result</span><span class="o">&lt;*</span><span class="k">mut</span> <span class="kt">u8</span><span class="p">,</span> <span class="p">()</span><span class="o">&gt;</span> <span class="p">{</span>
<span class="k">if</span> <span class="kd">let</span> <span class="nb">Ok</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="o">=</span> <span class="n">alloc_first_fit</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">head</span><span class="p">,</span> <span class="n">policy</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">Ok</span><span class="p">(</span><span class="n">result</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">let</span> <span class="n">cell</span> <span class="o">=</span> <span class="n">policy</span><span class="p">.</span><span class="n">new_cell_for_free_list</span><span class="p">(</span><span class="n">size</span><span class="p">)</span><span class="o">?</span><span class="p">;</span>
<span class="kd">let</span> <span class="n">head</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">cell</span><span class="p">).</span><span class="n">insert_into_free_list</span><span class="p">(</span><span class="n">head</span><span class="p">,</span> <span class="n">policy</span><span class="p">);</span>
<span class="n">alloc_first_fit</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">head</span><span class="p">,</span> <span class="n">policy</span><span class="p">)</span>
<span class="p">}</span></code></pre></figure>
<p>But where do we get the free list heads from? The <code>WeeAlloc</code> structure holds the
head of the main free list, and if size classes are enabled, the size classes’
free list heads.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">pub</span> <span class="k">struct</span> <span class="n">WeeAlloc</span> <span class="p">{</span>
<span class="n">head</span><span class="o">:</span> <span class="n">imp</span><span class="o">::</span><span class="n">Exclusive</span><span class="o">&lt;*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="o">&gt;</span><span class="p">,</span>
<span class="cp">#[cfg(feature = </span><span class="s">"size_classes"</span><span class="cp">)]</span>
<span class="n">size_classes</span><span class="o">:</span> <span class="n">SizeClasses</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">struct</span> <span class="n">SizeClasses</span><span class="p">(</span>
<span class="p">[</span><span class="n">imp</span><span class="o">::</span><span class="n">Exclusive</span><span class="o">&lt;*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="o">&gt;</span><span class="p">;</span> <span class="n">SizeClasses</span><span class="o">::</span><span class="n">NUM_SIZE_CLASSES</span><span class="p">],</span>
<span class="p">);</span>
<span class="k">impl</span> <span class="n">SizeClasses</span> <span class="p">{</span>
<span class="k">pub</span> <span class="kr">const</span> <span class="n">NUM_SIZE_CLASSES</span><span class="o">:</span> <span class="n">usize</span> <span class="o">=</span> <span class="mi">256</span><span class="p">;</span>
<span class="k">pub</span> <span class="k">fn</span> <span class="n">get</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="o">:</span> <span class="n">Words</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="n">imp</span><span class="o">::</span><span class="n">Exclusive</span><span class="o">&lt;*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="o">&gt;&gt;</span> <span class="p">{</span>
<span class="bp">self</span><span class="p">.</span><span class="mf">0.</span><span class="n">get</span><span class="p">(</span><span class="n">size</span><span class="p">.</span><span class="mi">0</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>As you can see, every free list head is wrapped in an <code>imp::Exclusive</code>.</p>
<p>The <code>imp</code> module contains target-specific implementation code and comes in two
flavors: <code>imp_wasm32.rs</code> and <code>imp_unix.rs</code>. The <code>alloc_pages</code> function we saw
earlier is defined in <code>imp_wasm32.rs</code>. There is another <code>alloc_pages</code> function
that uses <code>mmap</code> inside <code>imp_unix.rs</code>. The <code>imp::Exclusive</code> wrapper type
guarantees exclusive access to its inner value. For WebAssembly, this is a
no-op, since <code>SharedArrayBuffer</code>s aren’t shipping and there is no shared-data
threading. For unix systems, this protects the inner value in a pthread mutex,
and is similar to <code>std::sync::Mutex</code> but provides a <code>FnOnce</code> interface rather
than an RAII guard.</p>
<p>If size classes are not enabled, we always use the main free list head and the
<code>LargeAllocPolicy</code>. If size classes are enabled, we try to get the appropriate
size class’s free list head, and if that works, then we use the
<code>SizeClassAllocPolicy</code> with it. If there is no size class for the requested
allocation size, then we fall back to the main free list and the
<code>LargeAllocPolicy</code>.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">impl</span> <span class="n">WeeAlloc</span> <span class="p">{</span>
<span class="cp">#[cfg(feature = </span><span class="s">"size_classes"</span><span class="cp">)]</span>
<span class="k">unsafe</span> <span class="k">fn</span> <span class="n">with_free_list_and_policy_for_size</span><span class="o">&lt;</span><span class="n">F</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="o">:</span> <span class="n">Words</span><span class="p">,</span> <span class="n">f</span><span class="o">:</span> <span class="n">F</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">T</span>
<span class="n">where</span>
<span class="n">F</span><span class="o">:</span> <span class="k">for</span><span class="o">&lt;</span><span class="nl">'a</span><span class="o">&gt;</span> <span class="n">FnOnce</span><span class="p">(</span><span class="o">&amp;</span><span class="n">'a</span> <span class="k">mut</span> <span class="o">*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">'a</span> <span class="n">AllocPolicy</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">T</span><span class="p">,</span>
<span class="p">{</span>
<span class="k">if</span> <span class="kd">let</span> <span class="nb">Some</span><span class="p">(</span><span class="n">head</span><span class="p">)</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">size_classes</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">size</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">policy</span> <span class="o">=</span> <span class="n">size_classes</span><span class="o">::</span><span class="n">SizeClassAllocPolicy</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">.</span><span class="n">head</span><span class="p">);</span>
<span class="kd">let</span> <span class="n">policy</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">policy</span> <span class="k">as</span> <span class="o">&amp;</span><span class="n">AllocPolicy</span><span class="p">;</span>
<span class="n">head</span><span class="p">.</span><span class="n">with_exclusive_access</span><span class="p">(</span><span class="o">|</span><span class="n">head</span><span class="o">|</span> <span class="n">f</span><span class="p">(</span><span class="n">head</span><span class="p">,</span> <span class="n">policy</span><span class="p">))</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">policy</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">LARGE_ALLOC_POLICY</span> <span class="k">as</span> <span class="o">&amp;</span><span class="n">AllocPolicy</span><span class="p">;</span>
<span class="bp">self</span><span class="p">.</span><span class="n">head</span><span class="p">.</span><span class="n">with_exclusive_access</span><span class="p">(</span><span class="o">|</span><span class="n">head</span><span class="o">|</span> <span class="n">f</span><span class="p">(</span><span class="n">head</span><span class="p">,</span> <span class="n">policy</span><span class="p">))</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="cp">#[cfg(not(feature = </span><span class="s">"size_classes"</span><span class="cp">))]</span>
<span class="k">unsafe</span> <span class="k">fn</span> <span class="n">with_free_list_and_policy_for_size</span><span class="o">&lt;</span><span class="n">F</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="o">:</span> <span class="n">Words</span><span class="p">,</span> <span class="n">f</span><span class="o">:</span> <span class="n">F</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">T</span>
<span class="n">where</span>
<span class="n">F</span><span class="o">:</span> <span class="k">for</span><span class="o">&lt;</span><span class="nl">'a</span><span class="o">&gt;</span> <span class="n">FnOnce</span><span class="p">(</span><span class="o">&amp;</span><span class="n">'a</span> <span class="k">mut</span> <span class="o">*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">'a</span> <span class="n">AllocPolicy</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">T</span><span class="p">,</span>
<span class="p">{</span>
<span class="kd">let</span> <span class="n">policy</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">LARGE_ALLOC_POLICY</span> <span class="k">as</span> <span class="o">&amp;</span><span class="n">AllocPolicy</span><span class="p">;</span>
<span class="bp">self</span><span class="p">.</span><span class="n">head</span><span class="p">.</span><span class="n">with_exclusive_access</span><span class="p">(</span><span class="o">|</span><span class="n">head</span><span class="o">|</span> <span class="n">f</span><span class="p">(</span><span class="n">head</span><span class="p">,</span> <span class="n">policy</span><span class="p">))</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>Finally, all that is left is to tie everything together to implement the <code>alloc</code>
method for the <code>Alloc</code> trait:</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">unsafe</span> <span class="k">impl</span><span class="o">&lt;</span><span class="nl">'a</span><span class="o">&gt;</span> <span class="n">Alloc</span> <span class="k">for</span> <span class="o">&amp;</span><span class="n">'a</span> <span class="n">WeeAlloc</span> <span class="p">{</span>
<span class="k">unsafe</span> <span class="k">fn</span> <span class="n">alloc</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">,</span> <span class="n">layout</span><span class="o">:</span> <span class="n">Layout</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Result</span><span class="o">&lt;*</span><span class="k">mut</span> <span class="kt">u8</span><span class="p">,</span> <span class="n">AllocErr</span><span class="o">&gt;</span> <span class="p">{</span>
<span class="k">if</span> <span class="n">layout</span><span class="p">.</span><span class="n">align</span><span class="p">()</span> <span class="o">&gt;</span> <span class="n">mem</span><span class="o">::</span><span class="n">size_of</span><span class="o">::&lt;</span><span class="n">usize</span><span class="o">&gt;</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">Err</span><span class="p">(</span><span class="n">AllocErr</span><span class="o">::</span><span class="n">Unsupported</span> <span class="p">{</span>
<span class="n">details</span><span class="o">:</span> <span class="s">"wee_alloc cannot align to more than word alignment"</span><span class="p">,</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="kd">let</span> <span class="n">size</span> <span class="o">=</span> <span class="n">Bytes</span><span class="p">(</span><span class="n">layout</span><span class="p">.</span><span class="n">size</span><span class="p">());</span>
<span class="k">if</span> <span class="n">size</span><span class="p">.</span><span class="mi">0</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">Ok</span><span class="p">(</span><span class="mh">0x1</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="kt">u8</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">let</span> <span class="n">size</span><span class="o">:</span> <span class="n">Words</span> <span class="o">=</span> <span class="n">size</span><span class="p">.</span><span class="n">round_up_to</span><span class="p">();</span>
<span class="bp">self</span><span class="p">.</span><span class="n">with_free_list_and_policy_for_size</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="o">|</span><span class="n">head</span><span class="p">,</span> <span class="n">policy</span><span class="o">|</span> <span class="p">{</span>
<span class="n">alloc_with_refill</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">head</span><span class="p">,</span> <span class="n">policy</span><span class="p">)</span>
<span class="p">.</span><span class="n">map_err</span><span class="p">(</span><span class="o">|</span><span class="p">()</span><span class="o">|</span> <span class="n">AllocErr</span><span class="o">::</span><span class="n">Exhausted</span> <span class="p">{</span> <span class="n">request</span><span class="o">:</span> <span class="n">layout</span> <span class="p">})</span>
<span class="p">})</span>
<span class="p">}</span>
<span class="p">...</span>
<span class="p">}</span></code></pre></figure>
<h4>Implementing Deallocation</h4>
<p>Deallocation either merges the just-freed block with one of its adjacent
neighbors, if they are also free, or it pushes the block onto the front of the
free list.</p>
<p>If we are reinserting a block into a size class’s free list, however, it doesn’t
make sense to merge blocks. Because the these free lists are always servicing
allocations of a single size, we would just end up re-splitting the merged block
back exactly as it is split now. There is no benefit to splitting and merging
and splitting again. Therefore, we have the <code>AllocPolicy</code> inform us whether
merging is desirable or not.</p>
<p>First, let’s examine deallocation without the details of merging. We get the
appropriate free list and allocation policy, and conjure up a reference to the
<code>AllocatedCell</code> that sits just before the data being freed. Then (assuming we
didn’t merge into another block that is already in the free list) we push the
block onto the front of the free list.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">unsafe</span> <span class="k">impl</span><span class="o">&lt;</span><span class="nl">'a</span><span class="o">&gt;</span> <span class="n">Alloc</span> <span class="k">for</span> <span class="o">&amp;</span><span class="n">'a</span> <span class="n">WeeAlloc</span> <span class="p">{</span>
<span class="p">...</span>
<span class="k">unsafe</span> <span class="k">fn</span> <span class="n">dealloc</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">,</span> <span class="n">ptr</span><span class="o">:</span> <span class="o">*</span><span class="k">mut</span> <span class="kt">u8</span><span class="p">,</span> <span class="n">layout</span><span class="o">:</span> <span class="n">Layout</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">size</span> <span class="o">=</span> <span class="n">Bytes</span><span class="p">(</span><span class="n">layout</span><span class="p">.</span><span class="n">size</span><span class="p">());</span>
<span class="k">if</span> <span class="n">size</span><span class="p">.</span><span class="mi">0</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">ptr</span><span class="p">.</span><span class="n">is_null</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">let</span> <span class="n">size</span><span class="o">:</span> <span class="n">Words</span> <span class="o">=</span> <span class="n">size</span><span class="p">.</span><span class="n">round_up_to</span><span class="p">();</span>
<span class="bp">self</span><span class="p">.</span><span class="n">with_free_list_and_policy_for_size</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="o">|</span><span class="n">head</span><span class="p">,</span> <span class="n">policy</span><span class="o">|</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">cell</span> <span class="o">=</span> <span class="p">(</span><span class="n">ptr</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="n">AllocatedCell</span><span class="p">).</span><span class="n">offset</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
<span class="kd">let</span> <span class="n">cell</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="n">cell</span><span class="p">;</span>
<span class="kd">let</span> <span class="n">free</span> <span class="o">=</span> <span class="n">cell</span><span class="p">.</span><span class="n">into_free_cell</span><span class="p">(</span><span class="n">policy</span><span class="p">);</span>
<span class="k">if</span> <span class="n">policy</span><span class="p">.</span><span class="n">should_merge_adjacent_free_cells</span><span class="p">()</span> <span class="p">{</span>
<span class="p">...</span>
<span class="p">}</span>
<span class="n">free</span><span class="p">.</span><span class="n">insert_into_free_list</span><span class="p">(</span><span class="n">head</span><span class="p">,</span> <span class="n">policy</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>When merging cells, the adjacent neighbor(s) we are merging into are also free,
and therefore are already inside the free list. Because our free list is
singly-linked, rather than doubly-linked, we can’t arbitrarily splice in new
elements when we have a handle to an element that is already in the free
list. This causes some hiccups.</p>
<p>Merging with the <em>previous</em> adjacent cell is still easy: it is already in the
free list, and we aren’t changing the location of the <code>CellHeader</code>, so folding
this cell into it is all that needs to be done. The free list can be left alone.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">if</span> <span class="n">policy</span><span class="p">.</span><span class="n">should_merge_adjacent_free_cells</span><span class="p">()</span> <span class="p">{</span>
<span class="k">if</span> <span class="kd">let</span> <span class="nb">Some</span><span class="p">(</span><span class="n">prev</span><span class="p">)</span> <span class="o">=</span> <span class="n">free</span><span class="p">.</span><span class="n">header</span>
<span class="p">.</span><span class="n">prev_cell</span><span class="p">()</span>
<span class="p">.</span><span class="n">and_then</span><span class="p">(</span><span class="o">|</span><span class="n">p</span><span class="o">|</span> <span class="p">(</span><span class="o">*</span><span class="n">p</span><span class="p">).</span><span class="n">as_free_cell_mut</span><span class="p">())</span>
<span class="p">{</span>
<span class="n">prev</span><span class="p">.</span><span class="n">header</span><span class="p">.</span><span class="n">next_cell_raw</span> <span class="o">=</span> <span class="n">free</span><span class="p">.</span><span class="n">header</span><span class="p">.</span><span class="n">next_cell_raw</span><span class="p">;</span>
<span class="k">if</span> <span class="kd">let</span> <span class="nb">Some</span><span class="p">(</span><span class="n">next</span><span class="p">)</span> <span class="o">=</span> <span class="n">free</span><span class="p">.</span><span class="n">header</span><span class="p">.</span><span class="n">next_cell</span><span class="p">()</span> <span class="p">{</span>
<span class="p">(</span><span class="o">*</span><span class="n">next</span><span class="p">).</span><span class="n">prev_cell_raw</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">prev</span><span class="p">.</span><span class="n">header</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">...</span>
<span class="p">}</span></code></pre></figure>
<p>Merging with the <em>next</em> adjacent cell is a little harder. It is already in the
free list, but we need to splice it out from the free list, since its header
will become invalid after consolidation, and it is <em>this</em> cell’s header that
needs to be in the free list. But, because the free list is singly-linked, we
don’t have access to the pointer pointing to the soon-to-be-invalid header, and
therefore can’t update that pointer to point to the new cell header. So instead
we have a delayed consolidation scheme. We insert this cell just after the next
adjacent cell in the free list, and set the next adjacent cell’s
<code>NEXT_FREE_CELL_CAN_MERGE</code> bit.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">impl</span> <span class="n">FreeCell</span> <span class="p">{</span>
<span class="kr">const</span> <span class="n">NEXT_FREE_CELL_CAN_MERGE</span><span class="o">:</span> <span class="n">usize</span> <span class="o">=</span> <span class="mb">0b01</span><span class="p">;</span>
<span class="kr">const</span> <span class="n">_RESERVED</span><span class="o">:</span> <span class="n">usize</span> <span class="o">=</span> <span class="mb">0b10</span><span class="p">;</span>
<span class="kr">const</span> <span class="n">MASK</span><span class="o">:</span> <span class="n">usize</span> <span class="o">=</span> <span class="o">!</span><span class="mb">0b11</span><span class="p">;</span>
<span class="k">fn</span> <span class="n">next_free_can_merge</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">bool</span> <span class="p">{</span>
<span class="bp">self</span><span class="p">.</span><span class="n">next_free_raw</span> <span class="k">as</span> <span class="n">usize</span> <span class="o">&amp;</span> <span class="n">Self</span><span class="o">::</span><span class="n">NEXT_FREE_CELL_CAN_MERGE</span> <span class="o">!=</span> <span class="mi">0</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="n">set_next_free_can_merge</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">next_free</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">next_free_raw</span> <span class="k">as</span> <span class="n">usize</span><span class="p">;</span>
<span class="kd">let</span> <span class="n">next_free</span> <span class="o">=</span> <span class="n">next_free</span> <span class="o">|</span> <span class="n">Self</span><span class="o">::</span><span class="n">NEXT_FREE_CELL_CAN_MERGE</span><span class="p">;</span>
<span class="bp">self</span><span class="p">.</span><span class="n">next_free_raw</span> <span class="o">=</span> <span class="n">next_free</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="n">next_free</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="o">*</span><span class="k">mut</span> <span class="n">FreeCell</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">next_free</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">next_free_raw</span> <span class="k">as</span> <span class="n">usize</span> <span class="o">&amp;</span> <span class="n">Self</span><span class="o">::</span><span class="n">MASK</span><span class="p">;</span>
<span class="n">next_free</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="n">FreeCell</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">unsafe</span> <span class="k">impl</span><span class="o">&lt;</span><span class="nl">'a</span><span class="o">&gt;</span> <span class="n">Alloc</span> <span class="k">for</span> <span class="o">&amp;</span><span class="n">'a</span> <span class="n">WeeAlloc</span> <span class="p">{</span>
<span class="p">...</span>
<span class="k">unsafe</span> <span class="k">fn</span> <span class="n">dealloc</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">,</span> <span class="n">ptr</span><span class="o">:</span> <span class="o">*</span><span class="k">mut</span> <span class="kt">u8</span><span class="p">,</span> <span class="n">layout</span><span class="o">:</span> <span class="n">Layout</span><span class="p">)</span> <span class="p">{</span>
<span class="p">...</span>
<span class="k">if</span> <span class="n">policy</span><span class="p">.</span><span class="n">should_merge_adjacent_free_cells</span><span class="p">()</span> <span class="p">{</span>
<span class="p">...</span>
<span class="k">if</span> <span class="kd">let</span> <span class="nb">Some</span><span class="p">(</span><span class="n">next</span><span class="p">)</span> <span class="o">=</span> <span class="n">free</span><span class="p">.</span><span class="n">header</span>
<span class="p">.</span><span class="n">next_cell</span><span class="p">()</span>
<span class="p">.</span><span class="n">and_then</span><span class="p">(</span><span class="o">|</span><span class="n">n</span><span class="o">|</span> <span class="p">(</span><span class="o">*</span><span class="n">n</span><span class="p">).</span><span class="n">as_free_cell_mut</span><span class="p">())</span>
<span class="p">{</span>
<span class="n">free</span><span class="p">.</span><span class="n">next_free_raw</span> <span class="o">=</span> <span class="n">next</span><span class="p">.</span><span class="n">next_free</span><span class="p">();</span>
<span class="n">next</span><span class="p">.</span><span class="n">next_free_raw</span> <span class="o">=</span> <span class="n">free</span><span class="p">;</span>
<span class="n">next</span><span class="p">.</span><span class="n">set_next_free_can_merge</span><span class="p">();</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">...</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>Then, the next time that we walk the free list for allocation, the bit will be
checked and the consolidation will happen at that time. Which means that the
<code>walk_free_list</code> definition we showed earlier was incomplete, since it didn’t
include the code for consolidation. Here is its complete definition:</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">unsafe</span> <span class="k">fn</span> <span class="n">walk_free_list</span><span class="o">&lt;</span><span class="n">F</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span><span class="p">(</span>
<span class="n">head</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="p">,</span>
<span class="n">policy</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">AllocPolicy</span><span class="p">,</span>
<span class="k">mut</span> <span class="n">f</span><span class="o">:</span> <span class="n">F</span><span class="p">,</span>
<span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="p">()</span><span class="o">&gt;</span>
<span class="n">where</span>
<span class="n">F</span><span class="o">:</span> <span class="n">FnMut</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="p">,</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">,</span>
<span class="p">{</span>
<span class="kd">let</span> <span class="k">mut</span> <span class="n">previous_free</span> <span class="o">=</span> <span class="n">head</span><span class="p">;</span>
<span class="k">loop</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">current_free</span> <span class="o">=</span> <span class="o">*</span><span class="n">previous_free</span><span class="p">;</span>
<span class="k">if</span> <span class="n">current_free</span><span class="p">.</span><span class="n">is_null</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">Err</span><span class="p">(());</span>
<span class="p">}</span>
<span class="kd">let</span> <span class="k">mut</span> <span class="n">current_free</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="n">current_free</span><span class="p">;</span>
<span class="k">if</span> <span class="n">policy</span><span class="p">.</span><span class="n">should_merge_adjacent_free_cells</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">// Now check if this cell can merge with the next cell in the free</span>
<span class="c1">// list. We do this after the initial allocation attempt so that we</span>
<span class="c1">// don't merge, only to immediately split the cell again right</span>
<span class="c1">// afterwards.</span>
<span class="k">while</span> <span class="n">current_free</span><span class="p">.</span><span class="n">next_free_can_merge</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">let</span> <span class="n">prev_adjacent</span> <span class="o">=</span> <span class="n">current_free</span><span class="p">.</span><span class="n">header</span><span class="p">.</span><span class="n">prev_cell_raw</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="n">FreeCell</span><span class="p">;</span>
<span class="kd">let</span> <span class="n">prev_adjacent</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="n">prev_adjacent</span><span class="p">;</span>
<span class="n">prev_adjacent</span><span class="p">.</span><span class="n">header</span><span class="p">.</span><span class="n">next_cell_raw</span> <span class="o">=</span> <span class="n">current_free</span><span class="p">.</span><span class="n">header</span><span class="p">.</span><span class="n">next_cell_raw</span><span class="p">;</span>
<span class="k">if</span> <span class="kd">let</span> <span class="nb">Some</span><span class="p">(</span><span class="n">next</span><span class="p">)</span> <span class="o">=</span> <span class="n">current_free</span><span class="p">.</span><span class="n">header</span><span class="p">.</span><span class="n">next_cell</span><span class="p">()</span> <span class="p">{</span>
<span class="p">(</span><span class="o">*</span><span class="n">next</span><span class="p">).</span><span class="n">prev_cell_raw</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">prev_adjacent</span><span class="p">.</span><span class="n">header</span><span class="p">;</span>
<span class="p">}</span>
<span class="o">*</span><span class="n">previous_free</span> <span class="o">=</span> <span class="n">prev_adjacent</span><span class="p">;</span>
<span class="n">current_free</span> <span class="o">=</span> <span class="n">prev_adjacent</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">if</span> <span class="kd">let</span> <span class="nb">Some</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">previous_free</span><span class="p">,</span> <span class="n">current_free</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">Ok</span><span class="p">(</span><span class="n">result</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">previous_free</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">current_free</span><span class="p">.</span><span class="n">next_free_raw</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>On the other hand, if <em>both</em> the previous and next adjacent cells are free, we
are faced with a dilemma. We cannot merge all the previous, current, and next
cells together because our singly-linked free list doesn’t allow for that kind
of arbitrary appending and splicing in <em>O(1)</em> time. Instead, we use a heuristic
to choose whether to merge with the previous or next adjacent cell. We could
choose to merge with whichever neighbor cell is smaller or larger, but we
don’t. Right now, we prefer the previous adjacent cell because we can greedily
consolidate with it immediately, whereas the consolidating with the next
adjacent cell must be delayed, as explained above.</p>
<p>If we made the minimum allocation size two words, then we would have room for a
doubly-linked free list, and could support consolidating previous, current, and
next free cell neighbors. We could also remove the delayed consolidation scheme,
which would further simplify a bunch of code. But it would mean effectively
three words of overhead for single word heap allocations. It isn’t clear to me
whether or not that trade off is worth it or not. To make an informed decision,
we’d need a corpus of allocations and frees made by typical WebAssembly
applications.</p>
<h3>Conclusion</h3>
<p><code>wee_alloc</code> is a work-in-progress prototype, but it already meets its goal of
being small.</p>
<p>However, it is certainly lacking in other areas. <a href="https://github.com/pepyakin">Sergey Pepyakin</a>
tried <a href="https://github.com/fitzgen/wee_alloc/issues/10">bootstrapping <code>rustc</code> with <code>wee_alloc</code> enabled as the global
allocator</a>, and it is a couple orders of magnitude slower than
bootstrapping <code>rustc</code> with its default <code>jemalloc</code>. On the one hand,
bootstrapping <code>rustc</code> isn’t exactly the scenario <code>wee_alloc</code> was designed for,
and it isn’t surprising that this new, unoptimized prototype is slower than the
mature, production-grade <code>jemalloc</code>. Furthermore, I doubt that we can compete
with <code>jemalloc</code> on speed without regressing code size. But even so, I think
<code>wee_alloc</code> is slower than it should be, and I suspect that there are some
low-hanging fruit waiting to be plucked.</p>
<p>I would love, love, <strong><em>love</em></strong> some help building <code>wee_alloc</code> — it’s a lot
of fun! Are you interested in code golfing the smallest <code>.wasm</code> binaries? Do you
like nitty-gritty profiling and digging into performance? Is <code>wee_alloc</code> missing
some obviously-better technique that you’re familiar with? Want to help Rust be
<em>the</em> number one choice for compiling to WebAssembly? Fork the <a href="https://github.com/fitzgen/wee_alloc"><code>wee_alloc</code>
repository</a> on GitHub and then come join us in <a href="irc://irc.mozilla.org#rust-wasm"><code>#rust-wasm</code> on
<code>irc.mozilla.org</code></a> and introduce yourself!</p>
<p><em>Thanks to <a href="http://www.mythmon.com/">Mike Cooper</a> and <a href="https://github.com/mozkeeler">David
Keeler</a> for reading early drafts and providing
valuable feedback</em>.</p>
<hr />
<p><small><sup id="foot-0">0</sup> This will be unnecessary soon, since LLVM’s
linker, <a href="https://lld.llvm.org/"><code>lld</code></a>, is gaining support for WebAssembly, and already supports
this functionality. The Rust toolchain will also start using <code>lld</code> and then we
won’t need <code>wasm-gc</code> anymore. <a href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#back-foot-0">↩</a></small></p>
<p><small><sup id="foot-1">1</sup> Right now there is a single linear memory, but
it is expected that more address spaces will come. They would be useful for, for
example, referencing garbage-collected JavaScript or DOM objects directly from
WebAssembly code. <a href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#back-foot-1">↩</a></small></p>
<p><small><sup id="foot-2">2</sup> The <code>current_memory</code> and <code>grow_memory</code>
instructions will likely be <a href="https://github.com/WebAssembly/meetings/blob/master/2018/CG-01-26.md#rename-memory-operations">renamed</a> to <code>mem.size</code> and
<code>mem.grow</code>. <a href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#back-foot-2">↩</a></small></p>Fri, 09 Feb 2018 08:00:00 +0000Ryan Harter: Asking Questionstag:blog.harterrt.com,2018-02-09:preferred_media.htmlhttps://blog.harterrt.com/preferred_media.html
<p>Will posted a great article a couple weeks ago,
<a href="https://wlach.github.io/blog/2018/01/giving-and-receiving-help-at-mozilla/">Giving and Receiving Help at Mozilla</a>.
I have been meaning to write a similar article for a while now.
His post finally pushed me over the edge. </p>
<p>Be sure to read Will's post first.
The rest of this article is an addendum to his post.</p>
<h3>Avoid Context Free Pings</h3>
<p>Context free pings should be considered harmful.
These are pings like <code>ping</code> or <code>hey</code>.
The problem with context free pings are documented elsewhere
(<a href="http://edunham.net/2017/10/05/saying_ping.html">1</a>,
<a href="https://blogs.gnome.org/markmc/2014/02/20/naked-pings/">2</a>,
<a href="http://www.nohello.com/2013/01/please-dont-say-just-hello-in-chat.html">3</a>)
so I won't discuss them here.</p>
<h3>Pings are Ephemeral</h3>
<p>IRC and Slack are nice because they generate notifications.
If you need a quick response, IRC or Slack are the way to go.
I get Slack and IRC notifications on my phone, so I'm likely to respond quickly.
On the other hand, these notifications disappear easily,
which makes it easy for me to lose your message.
<strong>If you don't hear from me immediately, it's a good idea to send an email</strong>.</p>
<p>Otherwise, I don't mind pings at all.
Some folks worry about creating interruptions, but this isn't a problem for me.
I limit the notifications I get so <strong>if I don't want to get your notification, I won't</strong>.
If I'm looking at Slack, I'm already distracted.</p>
<p>In short, consider these rules of thumb:</p>
<ul>
<li>If it will take me <strong>less</strong> than 2m to respond to you and it's urgent, ping me</li>
<li>If it will take me <strong>more</strong> than 2m to respond to you and it's urgent, file a bug and ping me</li>
<li>If it's not urgent just email me</li>
</ul>
<h3>Prefer Open Channels</h3>
<p>I've spent a lot of time on documentation at Mozilla.
It's hard.
Our tools are constantly under development and our needs are always changing
so our documentation needs constant work.
<strong>Asking questions in the open reduces our documentation burden</strong>.</p>
<p><a href="http://www.bmannconsulting.com/archive/email-is-the-place-where-information-goes-to-die/">Email is where information goes to die</a>.
If we discuss a problem in a bug, that conversation is open and discoverable.
It's not always useful, but it's a huge win when it is.
<strong>File a bug instead of writing an email</strong>.
@mention me in on #fx-metrics instead of PM-ing me.
CC an open mailing list if you need to use email.</p>Fri, 09 Feb 2018 08:00:00 +0000Ryan T. HarterAndy McKay: Alternatives to vertical tabshttp://www.agmweb.ca/not-using-vertical-tabshttp://www.agmweb.ca/2018-02-09-not-using-vertical-tabs/
<p>For the longest time I've used vertical tabs in Firefox and I still find it odd that people don't use it more. It's a simple fact that a horizontal tab strip doesn't scale too well when you get lots of tabs.</p>
<p>Of course, for most users this isn't a problem, most users do not have a lot of tabs open according to <a href="https://telemetry.mozilla.org/new-pipeline/dist.html#!cumulative=0&amp;end_date=2018-02-08&amp;keys=__none__!__none__!__none__&amp;max_channel_version=nightly%252F60&amp;measure=TAB_COUNT&amp;min_channel_version=null&amp;processType=*&amp;product=Firefox&amp;sanitize=1&amp;sort_keys=submissions&amp;start_date=2018-01-22&amp;table=0&amp;trim=1&amp;use_submission_date=0">Firefox telemetry</a>:</p>
<p><a href="https://telemetry.mozilla.org/new-pipeline/dist.html#!cumulative=0&amp;end_date=2018-02-08&amp;keys=__none__!__none__!__none__&amp;max_channel_version=nightly%252F60&amp;measure=TAB_COUNT&amp;min_channel_version=null&amp;processType=*&amp;product=Firefox&amp;sanitize=1&amp;sort_keys=submissions&amp;start_date=2018-01-22&amp;table=0&amp;trim=1&amp;use_submission_date=0"><img src="http://www.agmweb.ca/files/tab-count.png" /></a></p>
<p>But if you have a few the title just gets squished and squished till it becomes a scroll bar. Vertical tabs look great for this giving you lots of title space on a wide monitor:</p>
<p><img src="http://www.agmweb.ca/files/tab-list-vertical.png" /></p>
<p>Firefox is <em>way better</em> at this than Chrome. I sat next to someone who had nothing but triangles as their tab bar in Chrome. How did they cope?</p>
<p><img src="http://www.agmweb.ca/files/tab-chrome.png" /></p>
<p>With the landing of the tab hiding API in WebExtensions in Firefox 59, I wanted to try and understand what the many people who were clamouring for this API wanted to do. So I wrote a <a href="https://addons.mozilla.org/en-US/firefox/addon/tab-hider/">quick extension that's pretty terrible</a>. It provided a "Hide this tab" context menu item on the tab to hide the tab. I then added a quick management page to list all the hidden pages.</p>
<p><img src="http://www.agmweb.ca/files/tab-hidden-list.png" /></p>
<p>That was ok, but clicking that menu item was tedious. So then I set it to just perform some actions for me. I've now got it set up to <em>hide</em> a tab if it hasn't been looked it for an hour. Then five hours after that, if I haven't opened it again, the extension just closes the tab.</p>
<p>I tried that for a week and found it pretty useful. Tabs that are hidden still show up in the awesome bar and as soon as I click on them, they come back instantly. Eventually they'll get closed. They'll still appear in the awesome bar and I can bring them back, just in a slower manner.</p>
<p>If I find myself saying "where was that tab..." I just go to the management view and its likely there.</p>
<p>This extension isn't perfect, but its enabled me to stop using vertical tabs most of the time and now I'm torn which workflow is better. Maybe some combination.</p>Fri, 09 Feb 2018 08:00:00 +0000Niko Matsakis: Maximally minimal specialization: always applicable implshttp://smallcultfollowing.com/babysteps/blog/2018/02/09/maximally-minimal-specialization-always-applicable-implshttp://smallcultfollowing.com/babysteps/blog/2018/02/09/maximally-minimal-specialization-always-applicable-impls/
<p>So
<a href="http://aturon.github.io/2018/02/09/amazing-week/">aturon wrote this beautiful post about what a good week it has been</a>.
In there, they wrote:</p>
<blockquote>
<p><strong>Breakthrough #2</strong>: @nikomatsakis had a eureka moment and figured out a
path to make specialization sound, while still supporting its most
important use cases (blog post forthcoming!). Again, this suddenly
puts specialization on the map for Rust Epoch 2018.</p>
</blockquote>
<p>Sheesh I wish they hadn’t written that! Now the pressure is on. Well,
here goes nothing =).</p>
<p><em>Anyway</em>, I’ve been thinking about the upcoming Rust Epoch. We’ve been
iterating over the final list of features to be included and I think
it seems pretty exciting. But there is one “fancy type system”
feature that’s been languishing for some time:
<strong>specialization</strong>. Accepted to much fanfare as <a href="https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md">RFC 1210</a>, we’ve
been kind of stuck since then trying to figure out how to solve an
underlying soundness challenge.</p>
<p>As aturon wrote, I <strong>think</strong> (and emphasis on think!) I may have a
solution. I call it the <strong>always applicable</strong> rule, but you might also
call it <strong>maximally minimal specialization</strong><sup id="fnref:early"><a class="footnote" href="http://smallcultfollowing.com/babysteps/blog/2018/02/09/maximally-minimal-specialization-always-applicable-impls/#fn:early">1</a></sup>.</p>
<p>Let’s be clear: <strong>this proposal does not support all the
specialization use cases originally envisioned</strong>. As the phrase
<em>maximally minimal</em> suggests, it works by focusing on a core set of
impls and accepting those. But that’s better than most of its
competitors! =) Better still, it leaves a route for future expansion.</p>
<h3 id="the-soundness-problem">The soundness problem</h3>
<p>I’ll just cover the soundness problem very briefly; Aaron wrote an
<a href="https://aturon.github.io/blog/2017/07/08/lifetime-dispatch/">excellent blog post</a> that covers the details. The crux of
the problem is that code generation wants to erase regions, but the
type checker doesn’t. This means that we can write specialization
impls that depend on details of lifetimes, but we have no way to test
at code generation time if those more specialized impls apply. A very
simple example would be something like this:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">Trait</span> <span class="k">for</span> <span class="n">T</span> <span class="p">{</span> <span class="p">}</span>
<span class="k">impl</span> <span class="n">Trait</span> <span class="k">for</span> <span class="o">&amp;</span><span class="err">'</span><span class="k">static</span> <span class="nb">str</span> <span class="p">{</span> <span class="p">}</span>
</code></pre>
</div>
<p>At code generation time, all we know is that we have a <code class="highlighter-rouge">&amp;str</code> – for
<strong>some lifetime</strong>. We don’t know if it’s a static lifetime or not. The
type checker is supposed to have assured us that <strong>we don’t have to
know</strong> – that this lifetime is “big enough” to cover all the uses of
the string.</p>
<p>My proposal would reject the specializing impl above. I basically aim
to solve this problem by guaranteeing that, just as today, code
generation <strong>doesn’t have to care</strong> about specific lifetimes, because
it knows that – whatever they are – if there is a potentially
specializing impl, it will be applicable.</p>
<h3 id="the-always-applicable-test">The “always applicable” test</h3>
<p>The core idea is to change the rule for when overlap is allowed. In
<a href="https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md">RFC 1210</a> the rule is something like this:</p>
<ul>
<li>Distinct impls A and B are allowed to overlap if one of them
<em>specializes</em> the other.</li>
</ul>
<p>We have long intended to extend this via the idea of <a href="http://smallcultfollowing.com/babysteps/blog/2016/09/24/intersection-impls/">intersection impls</a>,
giving rise to a rule like:</p>
<ul>
<li>Two distinct impls A and B are allowed to overlap if, for all
types in their intersection:
<ul>
<li>there exists an applicable impl C and C <em>specializes</em> both A and B.<sup id="fnref:reflexive"><a class="footnote" href="http://smallcultfollowing.com/babysteps/blog/2018/02/09/maximally-minimal-specialization-always-applicable-impls/#fn:reflexive">2</a></sup></li>
</ul>
</li>
</ul>
<p>My proposal is to extend that intersection rule with the <em>always
applicable</em> test. I’m actually going to start with a simple version,
and then I’ll discuss an important extension that makes it much more
expressive.</p>
<ul>
<li>Two distinct impls A and B are allowed to overlap if, for all
types in their intersection:
<ul>
<li>there exists an applicable impl C and C <em>specializes</em> both A and B,</li>
<li><strong>and</strong> that impl C is <em>always applicable</em>.</li>
</ul>
</li>
</ul>
<p>(We will see, by the way, that the precise definition of the
<em>specializes</em> predicate doesn’t matter much for the purposes of my
proposal here – any partial order will do.)</p>
<h3 id="when-is-an-impl-always-applicable">When is an impl <em>always applicable</em>?</h3>
<p>Intuitively, an impl is <em>always applicable</em> if it does not impose any
additional conditions on its input types beyond that they be
well-formed – and in particular it doesn’t impose any equality
constraints between parts of its input types. It also has to be fully
generic with respect to the lifetimes involved.</p>
<p>Actually, I think the best way to explain it is in terms of the
<strong>implied bounds</strong> proposal<sup id="fnref:scalexm"><a class="footnote" href="http://smallcultfollowing.com/babysteps/blog/2018/02/09/maximally-minimal-specialization-always-applicable-impls/#fn:scalexm">3</a></sup> (<a href="https://github.com/rust-lang/rfcs/blob/master/text/2089-implied-bounds.md">RFC</a>, <a href="http://smallcultfollowing.com/babysteps/blog/2014/07/06/implied-bounds/">blog post</a>). The
idea is roughly this: an impl is <em>always applicable</em> if it meets three
conditions:</p>
<ul>
<li>it relies <strong>only</strong> on implied bounds,</li>
<li>it is fully generic with respect to lifetimes,</li>
<li>it doesn’t repeat generic type parameters.</li>
</ul>
<p>Let’s look at those three conditions.</p>
<h4 id="condition-1-relies-only-on-implied-bounds">Condition 1: Relies only on implied bounds.</h4>
<p>Here is an example of an <em>always applicable</em> impl (which could
therefore be used to specialize another impl):</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">struct</span> <span class="n">Foo</span><span class="o">&lt;</span><span class="n">T</span><span class="p">:</span> <span class="n">Clone</span><span class="o">&gt;</span> <span class="p">{</span> <span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">SomeTrait</span> <span class="k">for</span> <span class="n">Foo</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
<span class="c">// code in here can assume that `T: Clone` because of implied bounds</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Here the impl works fine, because it adds no additional bounds beyond
the <code class="highlighter-rouge">T: Clone</code> that is implied by the struct declaration.</p>
<p>If the <code class="highlighter-rouge">impl</code> adds new bounds that are not part of the struct,
however, then it is <strong>not always applicable</strong>:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">struct</span> <span class="n">Foo</span><span class="o">&lt;</span><span class="n">T</span><span class="p">:</span> <span class="n">Clone</span><span class="o">&gt;</span> <span class="p">{</span> <span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="p">:</span> <span class="nb">Copy</span><span class="o">&gt;</span> <span class="n">SomeTrait</span> <span class="k">for</span> <span class="n">Foo</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
<span class="c">// ^^^^^^^ new bound not declared on `Foo`,</span>
<span class="c">// hence *not* always applicable</span>
<span class="p">}</span>
</code></pre>
</div>
<h4 id="condition-2-fully-generic-with-respect-to-lifetimes">Condition 2: Fully generic with respect to lifetimes.</h4>
<p>Each lifetime used in the impl header must be a lifetime parameter,
and each lifetime parameter can only be used once. So an impl like
this is <strong>always applicable</strong>:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">impl</span><span class="o">&lt;</span><span class="err">'</span><span class="n">a</span><span class="p">,</span> <span class="err">'</span><span class="n">b</span><span class="o">&gt;</span> <span class="n">SomeTrait</span> <span class="k">for</span> <span class="o">&amp;</span><span class="err">'</span><span class="n">a</span> <span class="o">&amp;</span><span class="err">'</span><span class="n">b</span> <span class="nb">u32</span> <span class="p">{</span>
<span class="c">// implied bounds let us assume that `'b: 'a`, as well</span>
<span class="p">}</span>
</code></pre>
</div>
<p>But the following impls are <strong>not</strong> always applicable:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">impl</span><span class="o">&lt;</span><span class="err">'</span><span class="n">a</span><span class="o">&gt;</span> <span class="n">SomeTrait</span> <span class="k">for</span> <span class="o">&amp;</span><span class="err">'</span><span class="n">a</span> <span class="o">&amp;</span><span class="err">'</span><span class="n">a</span> <span class="nb">u32</span> <span class="p">{</span>
<span class="c">// ^^^^^^^ same lifetime used twice</span>
<span class="p">}</span>
<span class="k">impl</span> <span class="n">SomeTrait</span> <span class="k">for</span> <span class="o">&amp;</span><span class="err">'</span><span class="k">static</span> <span class="nb">str</span> <span class="p">{</span>
<span class="c">// ^^^^^^^ not a lifetime parmeter</span>
<span class="p">}</span>
</code></pre>
</div>
<h4 id="condition-3-each-type-parameter-can-only-be-used-once">Condition 3: Each type parameter can only be used once.</h4>
<p>Using a type parameter more than once imposes “hidden” equality constraints
between parts of the input types which in turn can lead to equality constraints
between lifetimes. Therefore, an <em>always applicable</em> impl must use each
type parameter only once, like this:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">U</span><span class="o">&gt;</span> <span class="n">SomeTrait</span> <span class="k">for</span> <span class="p">(</span><span class="n">T</span><span class="p">,</span> <span class="n">U</span><span class="p">)</span> <span class="p">{</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Repeating, as here, means the impl cannot be used to specialize:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">SomeTrait</span> <span class="k">for</span> <span class="p">(</span><span class="n">T</span><span class="p">,</span> <span class="n">T</span><span class="p">)</span> <span class="p">{</span>
<span class="c">// ^^^^</span>
<span class="c">// `T` used twice: not always applicable</span>
<span class="p">}</span>
</code></pre>
</div>
<h4 id="how-can-we-think-about-this-formally">How can we think about this formally?</h4>
<p>For each impl, we can create a Chalk goal that is provable if it is
always applicable. I’ll define this here “by example”. Let’s consider
a variant of the first example we saw:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">struct</span> <span class="n">Foo</span><span class="o">&lt;</span><span class="n">T</span><span class="p">:</span> <span class="n">Clone</span><span class="o">&gt;</span> <span class="p">{</span> <span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="p">:</span> <span class="n">Clone</span><span class="o">&gt;</span> <span class="n">SomeTrait</span> <span class="k">for</span> <span class="n">Foo</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
<span class="p">}</span>
</code></pre>
</div>
<p>As we saw before, this impl is <em>always applicable</em>, because the <code class="highlighter-rouge">T:
Clone</code> where clause on the impl follows from the implied bounds of
<code class="highlighter-rouge">Foo&lt;T&gt;</code>.</p>
<p>The recipe to transform this into a predicate is that we want to
replace each <em>use</em> of a type/region parameter in the input types with
a universally quantified type/region (note that the two uses of the
same type parameter would be replaced with two distinct types). This
yields a “skolemized” set of input types T. When check if the impl
could be applied to T.</p>
<p>In the case of our example, that means we would be trying to prove
something like this:</p>
<div class="highlighter-rouge"><pre class="highlight"><code>// For each *use* of a type parameter or region in
// the input types, we add a 'forall' variable here.
// In this example, the only spot is `Foo&lt;_&gt;`, so we
// have one:
forall&lt;A&gt; {
// We can assume that each of the input types (using those
// forall variables) are well-formed:
if (WellFormed(Foo&lt;A&gt;)) {
// Now we have to see if the impl matches. To start,
// we create existential variables for each of the
// impl's generic parameters:
exists&lt;T&gt; {
// The types in the impl header must be equal...
Foo&lt;T&gt; = Foo&lt;A&gt;,
// ...and the where clauses on the impl must be provable.
T: Clone,
}
}
}
</code></pre>
</div>
<p>Clearly, this is provable: we infer that <code class="highlighter-rouge">T = A</code>, and then we can
prove that <code class="highlighter-rouge">A: Clone</code> because it follows from
<code class="highlighter-rouge">WellFormed(Foo&lt;A&gt;)</code>. Now if we look at the second example, which
added <code class="highlighter-rouge">T: Copy</code> to the impl, we can see why we get an error. Here was
the example:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">struct</span> <span class="n">Foo</span><span class="o">&lt;</span><span class="n">T</span><span class="p">:</span> <span class="n">Clone</span><span class="o">&gt;</span> <span class="p">{</span> <span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="p">:</span> <span class="nb">Copy</span><span class="o">&gt;</span> <span class="n">SomeTrait</span> <span class="k">for</span> <span class="n">Foo</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
<span class="c">// ^^^^^^^ new bound not declared on `Foo`,</span>
<span class="c">// hence *not* always applicable</span>
<span class="p">}</span>
</code></pre>
</div>
<p>That example results in a query like:</p>
<div class="highlighter-rouge"><pre class="highlight"><code>forall&lt;A&gt; {
if (WellFormed(Foo&lt;A&gt;)) {
exists&lt;T&gt; {
Foo&lt;T&gt; = Foo&lt;A&gt;,
T: Copy, // &lt;-- Not provable!
}
}
}
</code></pre>
</div>
<p>In this case, we fail to prove <code class="highlighter-rouge">T: Copy</code>, because it does not follow
from <code class="highlighter-rouge">WellFormed(Foo&lt;A&gt;)</code>.</p>
<p>As one last example, let’s look at the impl that repeats a type parameter:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">SomeTrait</span> <span class="k">for</span> <span class="p">(</span><span class="n">T</span><span class="p">,</span> <span class="n">T</span><span class="p">)</span> <span class="p">{</span>
<span class="c">// Not always applicable</span>
<span class="p">}</span>
</code></pre>
</div>
<p>The query that will result follows; what is interesting here is that
the type <code class="highlighter-rouge">(T, T)</code> results in <em>two</em> forall variables, because it has
two distinct <em>uses</em> of a type parameter (it just happens to be one
parameter used twice):</p>
<div class="highlighter-rouge"><pre class="highlight"><code>forall&lt;A, B&gt; {
if (WellFormed((A, B))) {
exists&lt;T&gt; {
(T, T) = (A, B) // &lt;-- cannot be proven
}
}
}
</code></pre>
</div>
<h3 id="what-is-accepted">What is accepted?</h3>
<p>What this rule primarily does it allow you to specialize blanket impls
with concrete types. For example, we currently have a <code class="highlighter-rouge">From</code> impl
that says any type <code class="highlighter-rouge">T</code> can be converted to itself:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">From</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="k">for</span> <span class="n">T</span> <span class="p">{</span> <span class="err">..</span> <span class="p">}</span>
</code></pre>
</div>
<p>It would be nice to be able to define an impl that allows a value of
the never type <code class="highlighter-rouge">!</code> to be converted into <em>any</em> type (since such a value
cannot exist in practice:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">From</span><span class="o">&lt;!&gt;</span> <span class="k">for</span> <span class="n">T</span> <span class="p">{</span> <span class="err">..</span> <span class="p">}</span>
</code></pre>
</div>
<p>However, this impl overlaps with the reflexive impl. Therefore, we’d
like to be able to provide an intersection impl defining what happens
when you convert <code class="highlighter-rouge">!</code> to <code class="highlighter-rouge">!</code> specifically:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">impl</span> <span class="n">From</span><span class="o">&lt;!&gt;</span> <span class="k">for</span> <span class="o">!</span> <span class="p">{</span> <span class="err">..</span> <span class="p">}</span>
</code></pre>
</div>
<p>All of these impls would be legal in this proposal.</p>
<h3 id="extension-refining-always-applicable-impls-to-consider-the-base-impl">Extension: Refining <em>always applicable</em> impls to consider the base impl</h3>
<p>While it accepts some things, the <em>always applicable</em> rule can also be
quite restrictive. For example, consider this pair of impls:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="c">// Base impl:</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">SomeTrait</span> <span class="k">for</span> <span class="n">T</span> <span class="n">where</span> <span class="n">T</span><span class="p">:</span> <span class="err">'</span><span class="k">static</span> <span class="p">{</span> <span class="p">}</span>
<span class="c">// Specializing impl:</span>
<span class="k">impl</span> <span class="n">SomeTrait</span> <span class="k">for</span> <span class="o">&amp;</span><span class="err">'</span><span class="k">static</span> <span class="nb">str</span> <span class="p">{</span> <span class="p">}</span>
</code></pre>
</div>
<p>Here, the second impl wants to specialize the first, but it is not
<em>always applicable</em>, because it specifies the <code class="highlighter-rouge">'static</code> lifetime. <em>And
yet,</em> it feels like this should be ok, since the base impl only
applies to <code class="highlighter-rouge">'static</code> things.</p>
<p>We can make this notion more formal by expanding the property to say
that the specializing impl C must be <em>always applicable</em> <strong>with
respect to the base impls</strong>. In this extended version of the
predicate, the impl C is allowed to rely not only on the <em>implied
bounds</em>, but on the <em>bounds that appear in the base impl(s)</em>.</p>
<p>So, the impls above might result in a Chalk predicate like:</p>
<div class="highlighter-rouge"><pre class="highlight"><code>// One use of a lifetime in the specializing impl (`'static`),
// so we introduce one 'forall' lifetime:
forall&lt;'a&gt; {
// Assuming the base impl applies:
if (exists&lt;T&gt; { T = &amp;'a str, T: 'static }) {
// We have to prove that the
// specialized impls type's can unify:
&amp;'a str = &amp;'static str
}
}
}
</code></pre>
</div>
<p>As it happens, the compiler today has logic that would let us deduce
that, because we know that <code class="highlighter-rouge">&amp;'a str: 'static</code>, then we know that <code class="highlighter-rouge">'a =
'static</code>, and hence we could solve this clause successfully.</p>
<p>This rule also allows us to accept some cases where type parameters
are repeated, though we’d have to upgrade chalk’s capability to let it
prove those predicates fully. Consider this pair of impls from
<a href="https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md">RFC 1210</a>:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="c">// Base impl:</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">E</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span> <span class="n">Extend</span><span class="o">&lt;</span><span class="n">E</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span> <span class="k">for</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span> <span class="n">where</span> <span class="n">T</span><span class="p">:</span> <span class="n">IntoIterator</span><span class="o">&lt;</span><span class="n">Item</span><span class="o">=</span><span class="n">E</span><span class="o">&gt;</span> <span class="p">{</span><span class="err">..</span><span class="p">}</span>
<span class="c">// Specializing impl:</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="err">'</span><span class="n">a</span><span class="p">,</span> <span class="n">E</span><span class="o">&gt;</span> <span class="n">Extend</span><span class="o">&lt;</span><span class="n">E</span><span class="p">,</span> <span class="o">&amp;</span><span class="err">'</span><span class="n">a</span> <span class="p">[</span><span class="n">E</span><span class="p">]</span><span class="o">&gt;</span> <span class="k">for</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span> <span class="p">{</span><span class="err">..</span><span class="p">}</span>
<span class="c">// ^ ^ ^ E repeated three times!</span>
</code></pre>
</div>
<p>Here the specializing impl repeats the type parameter <code class="highlighter-rouge">E</code> three times!
However, looking at the base impl, we can see that all of those
repeats follow from the conditions on the base impl. The resulting
chalk predicate would be:</p>
<div class="highlighter-rouge"><pre class="highlight"><code>// The fully general form of specializing impl is
// &gt; impl&lt;A,'b,C,D&gt; Extend&lt;A, &amp;'b [C]&gt; for Vec&lt;D&gt;
forall&lt;A, 'b, C, D&gt; {
// Assuming the base impl applies:
if (exists&lt;E, T&gt; { E = A, T = &amp;'b [B], Vec&lt;D&gt; = Vec&lt;E&gt;, T: IntoIterator&lt;Item=E&gt; }) {
// Can we prove the specializing impl unifications?
exists&lt;'a, E&gt; {
E = A,
&amp;'a [E] = &amp;'b [C],
Vec&lt;E&gt; = Vec&lt;D&gt;,
}
}
}
</code></pre>
</div>
<p>This predicate should be provable – but there is a definite catch.
At the moment, these kinds of predicates fall outside the “Hereditary
Harrop” (HH) predicates that Chalk can handle. HH predicates do not
permit existential quantification and equality predicates as
hypotheses (i.e., in an <code class="highlighter-rouge">if (C) { ... }</code>). I can however imagine some
quick-n-dirty extensions that would cover these particular cases, and
of course there are more powerful proving techniques out there that we
could tinker with (though I might prefer to avoid that).</p>
<h3 id="extension-reverse-implied-bounds-rules">Extension: Reverse implied bounds rules</h3>
<p>While the previous examples ought to be provable, there are some other
cases that won’t work out without some further extension to Rust.
Consider this pair of impls:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">Foo</span> <span class="k">for</span> <span class="n">T</span> <span class="n">where</span> <span class="n">T</span><span class="p">:</span> <span class="n">Clone</span> <span class="p">{</span> <span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">Foo</span> <span class="k">for</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">where</span> <span class="n">T</span><span class="p">:</span> <span class="n">Clone</span> <span class="p">{</span> <span class="p">}</span>
</code></pre>
</div>
<p>Can we consider this second impl to be always applicable relative to
the first? Effectively this boils down to asking whether knowing
<code class="highlighter-rouge">Vec&lt;T&gt;: Clone</code> allows us to deduce that <code class="highlighter-rouge">T: Clone</code> – and right now, we can’t
know that. The problem is that the impls we have only go one way.
That is, given the following impl:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">Clone</span> <span class="k">for</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">where</span> <span class="n">T</span><span class="p">:</span> <span class="n">Clone</span> <span class="p">{</span> <span class="err">..</span> <span class="p">}</span>
</code></pre>
</div>
<p>we get a program clause like</p>
<div class="highlighter-rouge"><pre class="highlight"><code>forall&lt;T&gt; {
(Vec&lt;T&gt;: Clone) :- (T: Clone)
}
</code></pre>
</div>
<p>but we <em>need</em> the reverse:</p>
<div class="highlighter-rouge"><pre class="highlight"><code>forall&lt;T&gt; {
(T: Clone) :- (Vec&lt;T&gt;: Clone)
}
</code></pre>
</div>
<p>This is basically an extension of implied bounds; but we’d have to be careful.
If we just create those reverse rules for every impl, then it would mean that
removing a bound from an impl is a breaking change, and that’d be a shame.</p>
<p>We could address this in a few ways. The most obvious is that we might
permit people to annotate impls indicating that they represent minimal
conditions (i.e., that removing a bound is a breaking
change).</p>
<p>Alternatively, I feel like there is some sort of feature “waiting” out
there that lets us make richer promises about what sorts of trait
impls we might write in the future: this would be helpful also to
coherence, since knowing what impls will <em>not</em> be written lets us
permit more things in downstream crates. (For example, it’d be useful
to know that <code class="highlighter-rouge">Vec&lt;T&gt;</code> will <em>never</em> be <code class="highlighter-rouge">Copy</code>.)</p>
<h3 id="extension-designating-traits-as-specialization-predicates">Extension: Designating traits as “specialization predicates”</h3>
<p>However, even when we consider the base impl, and even if we have some
solution to reverse rules, we <em>still</em> can’t cover the use case of
having “overlapping blanket impls”, like these two:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">Skip</span> <span class="k">for</span> <span class="n">T</span> <span class="n">where</span> <span class="n">T</span><span class="p">:</span> <span class="n">Read</span> <span class="p">{</span> <span class="err">..</span> <span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">Skip</span> <span class="k">for</span> <span class="n">T</span> <span class="n">where</span> <span class="n">T</span><span class="p">:</span> <span class="n">Read</span> <span class="o">+</span> <span class="n">Seek</span> <span class="p">{</span> <span class="err">..</span> <span class="p">}</span>
</code></pre>
</div>
<p>Here we have a trait <code class="highlighter-rouge">Skip</code> that (presumably) lets us skip forward in
a file. We can supply one default implementation that works for any
reader, but it’s inefficient: it would just read and discard N
bytes. It’d be nice if we could provide a more efficient version for
those readers that implement <code class="highlighter-rouge">Seek</code>. Unfortunately, this second impl
is not <em>always applicable with respect to</em> the first impl – it adds a
new requirement, <code class="highlighter-rouge">T: Seek</code>, that does not follow from the bounds on
the first impl nor the implied bounds.</p>
<p>You might wonder why this is problematic in the first place. The danger is
that some other crate might have an impl for <code class="highlighter-rouge">Seek</code> that places lifetime constraints,
such as:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">impl</span> <span class="n">Seek</span> <span class="k">for</span> <span class="o">&amp;</span><span class="err">'</span><span class="k">static</span> <span class="n">Foo</span> <span class="p">{</span> <span class="p">}</span>
</code></pre>
</div>
<p>Now at code generation time, we won’t be able to tell if that impl
applies, since we’ll have erased the precise region.</p>
<p>However, what we <em>could</em> do is allow the <code class="highlighter-rouge">Seek</code> trait to be designated
as a <strong>specialization predicate</strong> (perhaps with an attribute like
<code class="highlighter-rouge">#[specialization_predicate]</code>). Traits marked as specialization
predicates would be limited so that every one of their impls must be
<em>always applicable</em> (our original predicate). This basically means
that, e.g., a “reader” cannot <em>conditionally</em> implement <code class="highlighter-rouge">Seek</code> – it
has to be always seekable, or never. When determining whether an impl
is <em>always applicable</em>, we can ignore where clauses that pertain to
<code class="highlighter-rouge">#[specialization_predicate]</code> traits.</p>
<p>Adding a <code class="highlighter-rouge">#[specialization_predicate]</code> attribute to an existing trait
would be a breaking change; removing it would be one too. However, it
would be possible to take existing traits and add “specialization
predicate” subtraits. For example, if the <code class="highlighter-rouge">Seek</code> trait already existed,
we might do this:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">Skip</span> <span class="k">for</span> <span class="n">T</span> <span class="n">where</span> <span class="n">T</span><span class="p">:</span> <span class="n">Read</span> <span class="p">{</span> <span class="err">..</span> <span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">Skip</span> <span class="k">for</span> <span class="n">T</span> <span class="n">where</span> <span class="n">T</span><span class="p">:</span> <span class="n">Read</span> <span class="o">+</span> <span class="n">SeekPredicate</span> <span class="p">{</span> <span class="err">..</span> <span class="p">}</span>
<span class="cp">#[specialization_predicate]</span>
<span class="k">trait</span> <span class="n">UnconditionalSeek</span><span class="p">:</span> <span class="n">Seek</span> <span class="p">{</span>
<span class="k">fn</span> <span class="nf">seek_predicate</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">n</span><span class="p">:</span> <span class="nb">usize</span><span class="p">)</span> <span class="p">{</span>
<span class="k">self</span><span class="nf">.seek</span><span class="p">(</span><span class="n">n</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Now streams that implement seek unconditionally (probably all of them)
can add <code class="highlighter-rouge">impl UnconditionalSeek for MyStream { }</code> and get the
optimization. Not as automatic as we might like, but could be worse.</p>
<h3 id="default-impls-need-not-be-always-applicable">Default impls need not be <em>always applicable</em></h3>
<p>This last example illustrates an interesting point. RFC 1210 described not
only specialization but also a more flexible form of defaults that go beyond
default methods in trait definitions. The idea was that you can define lots of defaults
using a <code class="highlighter-rouge">default impl</code>. So the <code class="highlighter-rouge">UnconditionalSeek</code> trait at the end of the last section
might also have been expressed:</p>
<div class="language-rust highlighter-rouge"><pre class="highlight"><code><span class="err">#</span><span class="p">[</span><span class="n">specialization_predicate</span><span class="p">]</span>
<span class="k">trait</span> <span class="n">UnconditionalSeek</span><span class="p">:</span> <span class="n">Seek</span> <span class="p">{</span>
<span class="p">}</span>
<span class="n">default</span> <span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="p">:</span> <span class="n">Seek</span><span class="o">&gt;</span> <span class="n">UnconditionalSeek</span> <span class="k">for</span> <span class="n">T</span> <span class="p">{</span>
<span class="k">fn</span> <span class="nf">seek_predicate</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">n</span><span class="p">:</span> <span class="nb">usize</span><span class="p">)</span> <span class="p">{</span>
<span class="k">self</span><span class="nf">.seek</span><span class="p">(</span><span class="n">n</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>The interesting thing about default impls is that they are not (yet) a
full impl. They only represent default methods that <em>real</em> impls can
draw upon, but users still have to write a real impl somewhere. This
means that they can be exempt from the rules about being <em>always
applicable</em> – those rules will be enforced at the real impl point.
Note for example that the default impl above is not always available,
as it depends on <code class="highlighter-rouge">Seek</code>, which is not an implied bound anywhere.</p>
<h3 id="conclusion">Conclusion</h3>
<p>I’ve presented a refinement of specialization in which we impose one
extra condition on the specializing impl: not only must it be a subset
of the base impl(s) that it specializes, it must be <em>always
applicable</em>, which means basically that if we are given a set of types T where we know:</p>
<ul>
<li>the base impl was proven by the type checker to apply to T</li>
<li>the types T were proven by the type checker to be well-formed</li>
<li>and the specialized impl unifies with the lifetime-erased versions of T</li>
</ul>
<p>then we know that the specialized impl applies.</p>
<p>The beauty of this approach compared with past approaches is that it
preserves the existing role of the type checker and the code
generator. As today in Rust, the type checker always knows the full
region details, but the code generator can just ignore them, and still
be assured that all region data will be valid when it is accessed.</p>
<p>This implies for example that we don’t need to impose the restrictions
that <a href="https://aturon.github.io/blog/2017/07/08/lifetime-dispatch/">aturon discussed in their blog post</a>: we can allow specialized
associated types to be resolved in full by the type checker as long as they are not marked
default, because there is no danger that the type checker and trans will come to different
conclusions.</p>
<h3 id="thoughts">Thoughts?</h3>
<p>I’ve opened
<a href="https://internals.rust-lang.org/t/blog-post-maximally-minimal-specialization-always-applicable-impls/6739">an internals thread on this post</a>. I’d
love to hear whether you see a problem with this approach. I’d also
like to hear about use cases that you have for specialization that you
think may not fit into this approach.</p>
<h3 id="footnotes">Footnotes</h3>
<div class="footnotes">
<ol>
<li id="fn:early">
<p>We don’t say it so much anymore, but in the olden days of Rust, the phrase “max min” was very “en vogue”; I think we picked it up from some ES6 proposals about the class syntax. <a class="reversefootnote" href="http://smallcultfollowing.com/babysteps/blog/2018/02/09/maximally-minimal-specialization-always-applicable-impls/#fnref:early">↩</a></p>
</li>
<li id="fn:reflexive">
<p>Note: an impl is said to <em>specialize</em> itself. <a class="reversefootnote" href="http://smallcultfollowing.com/babysteps/blog/2018/02/09/maximally-minimal-specialization-always-applicable-impls/#fnref:reflexive">↩</a></p>
</li>
<li id="fn:scalexm">
<p>Let me give a shout out here to scalexm, who recently <a href="https://github.com/rust-lang-nursery/chalk/pull/82">emerged with an elegant solution for how to model implied bounds in Chalk</a>. <a class="reversefootnote" href="http://smallcultfollowing.com/babysteps/blog/2018/02/09/maximally-minimal-specialization-always-applicable-impls/#fnref:scalexm">↩</a></p>
</li>
</ol>
</div>Fri, 09 Feb 2018 05:00:00 +0000Nicholas D. MatsakisAir Mozilla: Bay Area Rust Meetup February 2018https://air.mozilla.org/bay-area-rust-meetup-february-2018/https://air.mozilla.org/bay-area-rust-meetup-february-2018/
<p>
<img alt="Bay Area Rust Meetup February 2018" class="wp-post-image" height="90" src="https://air.cdn.mozilla.net/media/cache/87/4f/874f4abef76f55213d50e43d6417ed99.png" width="160" />
﻿ - Matthew Fornaciari from Gremlin talking about a version of Chaos Monkey in Rust - George Morgan from Flipper talking about their embedded Rust...
</p>Fri, 09 Feb 2018 03:00:00 +0000Air MozillaKarl Dubost: Pour holy Web Compatibility in your CSS fonttag:www.otsukare.info,2018-02-09:2018/02/09/android-font-csshttp://www.otsukare.info/2018/02/09/android-font-css
<p>Yet another Webcompat issue with the <a href="https://webcompat.com/issues/12993">characters being cut in the bottom</a>, this will join <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1392147">the other ones</a>, such as cross characters not well centered in a rounded box and many other cases. What about it?</p>
<h3>The <code>sans-serif</code> issue</h3>
<p>All of these have the same pattern. They rely on the <a href="http://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align">intrinsic font features</a> to get the right design. So… this morning was another of this case. Take this very simple CSS rule: </p>
<div class="highlight"><pre><span></span><span class="nc">.gsc-control-cse</span><span class="o">,</span> <span class="nc">.gsc-control-cse</span> <span class="nc">.gsc-table-result</span> <span class="p">{</span>
<span class="nb">width</span><span class="o">:</span> <span class="m">100%</span><span class="p">;</span>
<span class="nb">font-family</span><span class="o">:</span> <span class="n">Arial</span><span class="o">,</span> <span class="nb">sans-serif</span><span class="p">;</span>
<span class="nb">font-size</span><span class="o">:</span> <span class="m">13px</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>Nothing fancy about it. It includes <code>Arial</code>, a widely used font and it gives a <code>sans-serif</code> fallback. It seems to be a sound and fail-safe choice. </p>
<p>Well… meet the land of mobile and your font declaration doesn't seem to be that reliable anymore. <strong>Mobile browsers have different default fonts on Android.</strong> </p>
<p>The <code>sans-serif</code> doesn't mean the same thing in all browsers on the same OS.</p>
<p>For example, for sans-serif and western languages</p>
<ul>
<li>Chrome: Roboto</li>
<li>Firefox: Clear Sans</li>
</ul>
<p>If you use Chinese or Japanese characters, the default will be different. </p>
<h3>Fix The Users Woes On Mobile</h3>
<p>Why is it happening so often? Same story, the web developers didn't have time, budget to test on all browsers. They probably tested on Chrome and Safari (iOS) and they decided to make a pass on Firefox Android. And because fonts have <a href="http://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align">different features</a>, they do not behave the same to <code>line-height</code>, <code>box sizes</code> and so on. <code>Clear Sans</code> and <code>Roboto</code> are different enough that it creates breakage on some sites.</p>
<p>If you test only on Chrome Android (you should not), but let says we reached the shores of Friday… and it's time to deploy at 5pm. This is your fix:</p>
<div class="highlight"><pre><span></span><span class="nc">.gsc-control-cse</span><span class="o">,</span> <span class="nc">.gsc-control-cse</span> <span class="nc">.gsc-table-result</span> <span class="p">{</span>
<span class="nb">width</span><span class="o">:</span> <span class="m">100%</span><span class="p">;</span>
<span class="nb">font-family</span><span class="o">:</span> <span class="n">Arial</span><span class="o">,</span> <span class="n">Roboto</span><span class="o">,</span> <span class="nb">sans-serif</span><span class="p">;</span>
<span class="nb">font-size</span><span class="o">:</span> <span class="m">13px</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p><strong>Name the fonts available on mobile OS</strong>, you expect the design to be working on. It's still not universally accessible and will not make it reliable in all cases, but it will cover a lot of cases. It will also make your Firefox Android users less grumpy and your Mondays will be brighter.</p>
<p>Otsukare!</p>Fri, 09 Feb 2018 01:00:00 +0000Karl DubostHacks.Mozilla.Org: Creating an Add-on for the Project Things Gatewayhttps://hacks.mozilla.org/?p=31908https://hacks.mozilla.org/2018/02/creating-an-add-on-for-the-project-things-gateway/
<p>The <a href="https://iot.mozilla.org/gateway/" rel="noopener" target="_blank">Project Things Gateway</a> exists as a platform to bring all of your IoT devices together under a unified umbrella, using a standardized HTTP-based API. Currently, the platform only has support for a limited number of devices, and we need your help expanding our reach! It is fairly straightforward to add support for new devices, and we will walk you through how to do so. The best part: you can use whatever programming language you’d like!</p>
<h3>High-Level Concepts</h3>
<h4>Add-on</h4>
<p>An <em>Add-on</em> is a collection of code that the Gateway runs to gain a new features, usually a new adapter. This is loosely modeled after the <a href="https://developer.mozilla.org/en-US/Add-ons" rel="noopener" target="_blank">add-on system</a> in Firefox where each add-on adds to the functionality of your Gateway in new and exciting ways.</p>
<h4>Adapter</h4>
<p>An <em>Adapter</em> is an object that manages communication with a device or set of devices. This could be very granular, such as one adapter object communicating with one GPIO pin, or it could be much more broad, such as one adapter communicating with any number of devices over WiFi. You decide!</p>
<h4>Device</h4>
<p>A <em>Device</em> is just that, a hardware device, such as a smart plug, light bulb, or temperature sensor.</p>
<h4>Property</h4>
<p>A <em>Property</em> is an individual property of a device, such as its on/off state, its energy usage, or its color.</p>
<h3>Supported Languages</h3>
<p>Add-ons have been written in Node.js, Python, and Rust so far, and official JavaScript and Python bindings are available on the gateway platform. If you want to skip ahead, you can check out the <a href="https://hacks.mozilla.org/feed/#examples">list of examples</a> now. However, you are free to develop an add-on in whatever language you choose, provided the following:</p>
<ul>
<li>Your add-on is <a href="https://github.com/mozilla-iot/wiki/wiki/Add-On-System-Design" rel="noopener" target="_blank">properly packaged</a>.</li>
<li>Your add-on package bundles all required dependencies that do not already exist on the gateway platform.</li>
<li>If your package contains any compiled binaries, they must be compiled for the armv6l architecture. <a href="https://elinux.org/RPi_Hardware#Raspberry_Pi_Hardware_History" rel="noopener" target="_blank">All Raspberry Pi families</a> are compatible with this architecture. The easiest way to do this would be to build your package on a Raspberry Pi 1/2/Zero.</li>
</ul>
<h3>Implementation: The Nitty Gritty</h3>
<h4>Evaluate Your Target Device</h4>
<p>First, you need to think about the device(s) you’re trying to target.</p>
<ul>
<li>Will your add-on be communicating with one or many devices?</li>
<li>How will the add-on communicate with the device(s)? Is a separate hardware dongle required?
<ul>
<li>For example, the Zigbee and Z-Wave adapters require a separate USB dongle to communicate with devices.</li>
</ul>
</li>
<li>What properties do these devices have?</li>
<li>Is there an existing Thing type that you can advertise?</li>
<li>Are there existing libraries you can use to talk to your device?
<ul>
<li>You’d be surprised by how many NPM modules, Python modules, C/C++ libraries, etc. exist for communicating with IoT devices.</li>
</ul>
</li>
</ul>
<p>The key here is to gain a strong understanding of the devices you’re trying to support.</p>
<h4>Start from an Example</h4>
<p>The easiest way to start development is to start with one of the <a href="https://hacks.mozilla.org/feed/#examples">existing add-ons</a> (listed further down). You can download, copy and paste, or git clone one of them into:</p>
<pre><code>/home/pi/mozilla-iot/gateway/build/addons/</code></pre>
<p>Alternatively, you can do your development on a different machine. Just make sure you test on the Raspberry Pi.</p>
<p>After doing so, you should edit the <tt>package.json</tt> file as appropriate. In particular, the name field needs to match the name of the directory you just created.</p>
<p>Next, begin to edit the code. The key parts of the add-on lifecycle are device creation and property updates. Device creation typically happens as part of a discovery process, whether that’s through <a href="https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol" rel="noopener" target="_blank">SSDP</a>, probing serial devices, or something else. After discovering devices, you need to build up their property lists, and make sure you handle property changes (that could be through events you get, or you may have to poll your devices). You also need to handle property updates from the user.</p>
<p>Restart the gateway process to test your changes:</p>
<pre><code>$ sudo systemctl restart mozilla-iot-gateway.service</code></pre>
<p>Test your add-on thoroughly. You can enable it through the <em>Settings-&gt;Add-ons</em> menu in the UI.</p>
<h4>Get Your Add-on Published!</h4>
<p>Run <tt>./package.sh</tt> or whatever else you have to do to package up your add-on. Host the package somewhere, i.e. on Github as a release. Then, submit a pull request or issues to the addon-list repository.</p>
<h4>Notes</h4>
<ul>
<li>Your add-on will run in a separate process and communicate with the gateway process via nanomsg IPC. That should hopefully be irrelevant to you.</li>
<li>If your add-on process dies, it will automatically be restarted.</li>
</ul>
<h3>Examples</h3>
<p>The Project Things team has built several add-ons that can serve as a good starting point and reference.</p>
<p>Node.js:</p>
<ul>
<li>Example adapter: <a href="https://github.com/mozilla-iot/example-adapter" rel="noopener" target="_blank">https://github.com/mozilla-iot/example-adapter</a></li>
<li>Virtual things adapter: <a href="https://github.com/mozilla-iot/virtual-things-adapter" rel="noopener" target="_blank">https://github.com/mozilla-iot/virtual-things-adapter</a></li>
<li>Zigbee adapter: <a href="https://github.com/mozilla-iot/zigbee-adapter" rel="noopener" target="_blank">https://github.com/mozilla-iot/zigbee-adapter</a></li>
<li>Z-Wave adapter: <a href="https://github.com/mozilla-iot/zwave-adapter" rel="noopener" target="_blank">https://github.com/mozilla-iot/zwave-adapter</a></li>
<li>Philips Hue adapter: <a href="https://github.com/mozilla-iot/philips-hue-adapter" rel="noopener" target="_blank">https://github.com/mozilla-iot/philips-hue-adapter</a></li>
<li>GPIO adapter: <a href="https://github.com/mozilla-iot/gpio-adapter" rel="noopener" target="_blank">https://github.com/mozilla-iot/gpio-adapter</a></li>
</ul>
<p>Python:</p>
<ul>
<li>TP-Link adapter: <a href="https://github.com/mozilla-iot/tplink-adapter" rel="noopener" target="_blank">https://github.com/mozilla-iot/tplink-adapter</a></li>
</ul>
<p>Rust:</p>
<ul>
<li>MQTT adapter (in progress): <a href="https://github.com/hobinjk/mqtt-adapter" rel="noopener" target="_blank">https://github.com/hobinjk/mqtt-adapter</a></li>
</ul>
<h3>References</h3>
<p>Additional documentation, API references, etc., can be found here:</p>
<ul>
<li>Web Thing API specification: <a href="https://iot.mozilla.org/wot/" rel="noopener" target="_blank">https://iot.mozilla.org/wot/</a></li>
<li>Node.js adapter API: <a href="https://github.com/mozilla-iot/wiki/wiki/Adapter-API" rel="noopener" target="_blank">https://github.com/mozilla-iot/wiki/wiki/Adapter-API</a></li>
<li>Adapter IPC API: <a href="https://github.com/mozilla-iot/wiki/wiki/Adapter-IPC" rel="noopener" target="_blank">https://github.com/mozilla-iot/wiki/wiki/Adapter-IPC</a></li>
<li>Add-on packaging: <a href="https://github.com/mozilla-iot/wiki/wiki/Add-On-System-Design" rel="noopener" target="_blank">https://github.com/mozilla-iot/wiki/wiki/Add-On-System-Design</a></li>
<li>Python add-on bindings: <a href="https://github.com/mozilla-iot/gateway-addon-python" rel="noopener" target="_blank">https://github.com/mozilla-iot/gateway-addon-python</a></li>
<li>Add-on list: <a href="https://github.com/mozilla-iot/addon-list" rel="noopener" target="_blank">https://github.com/mozilla-iot/addon-list</a></li>
</ul>
<p>Find a bug in some of our software? Let us know! We’d love to have issues, or better yet, pull requests, filed to the appropriate Github repo.</p>Thu, 08 Feb 2018 22:01:53 +0000James HobinShing Lyu: Minimal React.js Without A Build Step (Updated)https://shinglyu.github.io/web/2018/02/08/minimal-react-js-without-a-build-step-updated.htmlhttps://shinglyu.github.io/web/2018/02/08/minimal-react-js-without-a-build-step-updated.html
<p>Back in 2016, I wrote a <a href="http://shinglyu.github.io/web/2016/04/06/minimal_react.html">post</a> about how to write a React.js page without a build step. If I remember correctly, at that time the official React.js site have very little information about running React.js without [Webpack][webpack], [in-browser Babel transpiler][babel] is not very stable and they are deprecating <code class="highlighter-rouge">JSXTransformer.js</code>. After the post my focus turned to browser backend projects and I haven’t touch React.js for a while. Now after 1.5 years, when I try to update one of [my React.js project][itinerary-viewer], I notice that the official site now has a clearer instruction on how to use React.js without a build step. So I’m going to write an update the post here.</p>
<p>You can find the example code on <a href="https://github.com/shinglyu/minimal-react">GitHub</a>.
</p>
<h4>1. Load React.js from CDN instead of npm</h4>
<p>You can use the official minimal HTML template <a href="https://reactjs.org/docs/try-react.html#minimal-html-template">here</a>. The most crucial bit is the importing of scripts:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"https://unpkg.com/react@16/umd/react.development.js"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"https://unpkg.com/react-dom@16/umd/react-dom.development.js"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"https://unpkg.com/babel-standalone@6.15.0/babel.min.js"</span><span class="nt">&gt;&lt;/script&gt;</span>
</code></pre></div></div>
<p>If you want better error message, you might want to add the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-crossorigin"><code class="highlighter-rouge">crossorigin</code></a> attribute to the <code class="highlighter-rouge">&lt;script&gt;</code> tags, as suggested in the <a href="https://reactjs.org/docs/cdn-links.html">official document</a>. Why the attribute you ask? As describe in <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-crossorigin">MDN</a>, this attribute will allow your page to log errors on CORS scripts loaded from the CDN.</p>
<p>If you are looking for better performance, load the <code class="highlighter-rouge">*.production.min.js</code> instead of <code class="highlighter-rouge">*.development.js</code>.</p>
<h4>2. Get rid of JSX</h4>
<p>I’m actually not that against JSX now, but If you don’t want to include the <code class="highlighter-rouge">babel.min.js</code> script, you can consider using the <code class="highlighter-rouge">React.createElement</code> function. Actually all JSX elements are syntatic sugar for calling <code class="highlighter-rouge">React.createElement()</code>. Here are some examples:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;h1&gt;</span>Hello Word<span class="nt">&lt;/h1&gt;</span>
</code></pre></div></div>
<p>can be written as</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">React</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s1">'h1'</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="s1">'Hello World'</span><span class="p">)</span>
</code></pre></div></div>
<p>And if you want to pass attributes around, you can do</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;div</span> <span class="na">onClick=</span><span class="s">{this.props.clickHandler}</span> <span class="na">data=</span><span class="s">{this.state.data}</span><span class="nt">&gt;</span>
Click Me!
<span class="nt">&lt;/div&gt;</span>
</code></pre></div></div>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">React</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span> <span class="p">{</span>
<span class="s1">'onClick'</span><span class="p">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">clickHandler</span><span class="p">,</span>
<span class="s1">'data'</span><span class="p">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">data</span>
<span class="p">},</span>
<span class="s1">'Click Me!'</span><span class="p">)</span>
</code></pre></div></div>
<p>Of course you can have nested elements:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;div&gt;</span>
<span class="nt">&lt;h1&gt;</span>Hello World<span class="nt">&lt;/h1&gt;</span>
<span class="nt">&lt;a&gt;</span>Click Me!<span class="nt">&lt;/a&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</code></pre></div></div>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">React</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span>
<span class="nx">React</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s1">'h1'</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="s1">'Hello World'</span><span class="p">)</span>
<span class="nx">React</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s1">'a'</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="s1">'Click Me!'</span><span class="p">)</span>
<span class="p">)</span>
</code></pre></div></div>
<p>You can read how this works in the <a href="https://reactjs.org/docs/react-without-jsx.html">official documentation</a>.</p>
<ol>
<li>Split the React.js code into separate files</li>
</ol>
<p>In the official <a href="https://reactjs.org/docs/try-react.html#minimal-html-template">HTML template</a>, they show how to write script directly in HTML like:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;html&gt;</span>
<span class="nt">&lt;body&gt;</span>
<span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"root"</span><span class="nt">&gt;&lt;/div&gt;</span>
<span class="nt">&lt;script </span><span class="na">type=</span><span class="s">"text/babel"</span><span class="nt">&gt;</span>
<span class="nx">ReactDOM</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span>
<span class="o">&lt;</span><span class="nx">h1</span><span class="o">&gt;</span><span class="nx">Hello</span><span class="p">,</span> <span class="nx">world</span><span class="o">!&lt;</span><span class="sr">/h1&gt;</span><span class="err">,
</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'root'</span><span class="p">)</span>
<span class="p">);</span>
<span class="nt">&lt;/script&gt;</span>
<span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</code></pre></div></div>
<p>But for real-word projects we usually don’t want to throw everything into one big HTML file. So you can put everything between <code class="highlighter-rouge">&lt;script&gt;</code> and <code class="highlighter-rouge">&lt;/script&gt;</code> in to a separate JavaScript file, let’s name it <code class="highlighter-rouge">app.js</code> and load it in the original HTML like so:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;html&gt;</span>
<span class="nt">&lt;body&gt;</span>
<span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"root"</span><span class="nt">&gt;&lt;/div&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"app.js"</span> <span class="na">type=</span><span class="s">"text/babel"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</code></pre></div></div>
<p>The pitfall here is that you must keep the <code class="highlighter-rouge">type="text/babel"</code> attribute if you wants to use JSX. Otherwise the js script will fail when it first reaches a JSX tag, resulting an error like this:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>SyntaxError: expected expression, got '&lt;'[Learn More] app.js:2:2
</code></pre></div></div>
<h3>Using 3rd-party NPM components</h3>
<h4>Modules with browser support</h4>
<p>You can find tons of ready-made React components on NPM, but the quality varies. Some of them are released with browser support, for example <a href="https://reactstrap.github.io/">Reactstrap</a>, which contains Bootstrap 4 components wrapped in React. In its documentation you can see a “CDN” section with a CDN link, which should just work by adding it to a script tag:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;!-- react-transition-group is required by reactstrap --&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"https://unpkg.com/react-transition-group@2.2.1/dist/react-transition-group.min.js"</span> <span class="na">charset=</span><span class="s">"utf-8"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"https://cdnjs.cloudflare.com/ajax/libs/reactstrap/4.8.0/reactstrap.min.js"</span> <span class="na">charset=</span><span class="s">"utf-8"</span><span class="nt">&gt;&lt;/script&gt;</span>
</code></pre></div></div>
<p>then you can find the components in a gloabl variable <code class="highlighter-rouge">Reactstrap</code>:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">"text/babel"</span> <span class="na">charset=</span><span class="s">"utf-8"</span><span class="nt">&gt;</span>
<span class="c1">// "Import" the components from Reactstrap</span>
<span class="kd">const</span> <span class="p">{</span><span class="nx">Button</span><span class="p">}</span> <span class="o">=</span> <span class="nx">Reactstrap</span><span class="p">;</span>
<span class="c1">// Render a Reactstrap Button element onto root</span>
<span class="nx">ReactDOM</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span>
<span class="o">&lt;</span><span class="nx">Button</span> <span class="nx">color</span><span class="o">=</span><span class="s2">"danger"</span><span class="o">&gt;</span><span class="nx">Hello</span><span class="p">,</span> <span class="nx">world</span><span class="o">!&lt;</span><span class="sr">/Button&gt;</span><span class="err">,
</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'root'</span><span class="p">)</span>
<span class="p">);</span>
<span class="nt">&lt;/script&gt;</span>
</code></pre></div></div>
<p>(In case you are curious, the first line is the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructurig.">destructing assignment of objects</a> in JavaScript).</p>
<p>Of course it also works without JSX:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">charset=</span><span class="s">"utf-8"</span><span class="nt">&gt;</span>
<span class="c1">// "Import" the components from Reactstrap</span>
<span class="kd">const</span> <span class="p">{</span><span class="nx">Button</span><span class="p">}</span> <span class="o">=</span> <span class="nx">Reactstrap</span><span class="p">;</span>
<span class="c1">// Render a Reactstrap Button element onto root</span>
<span class="nx">ReactDOM</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span>
<span class="nx">React</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="nx">Button</span><span class="p">,</span> <span class="p">{</span><span class="s1">'color'</span><span class="p">:</span> <span class="s1">'danger'</span><span class="p">},</span> <span class="s2">"Hello world!"</span><span class="p">),</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'root'</span><span class="p">),</span>
<span class="p">);</span>
<span class="nt">&lt;/script&gt;</span>
</code></pre></div></div>
<h4>Modules without browser support</h4>
<p>For modules without explicit browser support, you can still try to expose it to the browser with <a href="http://browserify.org/">Browserify</a>, as described in <a href="http://krasimirtsonev.com/blog/article/distributing-react-components-babel-browserify-webpack-uglifyjs">this post</a>. Browserify is a tool that converts a Node.js module into something a browser can take. There are two tricks here:</p>
<ol>
<li>Use the <code class="highlighter-rouge">--standalone</code> option so Browserify will expose the component under the <code class="highlighter-rouge">window</code> namespace, so you don’t need a module system to use it.</li>
<li>Use the <code class="highlighter-rouge">browserify-global-shim</code> plugin to strip all the usage of <code class="highlighter-rouge">React</code> and <code class="highlighter-rouge">ReactDOM</code> in the NPM module code, so it will use the <code class="highlighter-rouge">React</code> and <code class="highlighter-rouge">ReactDOM</code> we included using the <code class="highlighter-rouge">&lt;script&gt;</code> tags.</li>
</ol>
<p>I’ll use a very simple React component on NPM, <a href="https://www.npmjs.com/package/simple-react-modal">simple-react-modal</a>, to illustrate this. First, we download this module to see what it looks like:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm install simple-react-modal
</code></pre></div></div>
<p>If we go to <code class="highlighter-rouge">node_modules/simple-react-modal</code>, we can see a pre-built JavaScript package in the <code class="highlighter-rouge">dist</code> folder. Now we can install Browserify by <code class="highlighter-rouge">npm install -g browserify</code>. But we can’t just run it yet, because the code uses <code class="highlighter-rouge">require('react')</code> but we want to use our version loaded in the browser. So we need to install <code class="highlighter-rouge">npm install browserify-global-shim</code> and add the configuration to <code class="highlighter-rouge">package.json</code>:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// package.json</span>
<span class="s2">"browserify-global-shim"</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">"react"</span><span class="p">:</span> <span class="s2">"React"</span><span class="p">,</span>
<span class="s2">"react-dom"</span><span class="p">:</span> <span class="s2">"ReactDOM"</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Now we can run</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>browserify node_modules/simple-react-modal <span class="se">\</span>
<span class="nt">-o</span> simple-react-modal-browser.js <span class="se">\</span>
<span class="nt">--transform</span> browserify-global-shim <span class="se">\</span>
<span class="nt">--standalone</span> Modal
</code></pre></div></div>
<p>We’ll get a <code class="highlighter-rouge">simple-react-modal-browser.js</code> file, which we can just load in the browser using the <code class="highlighter-rouge">&lt;script&gt;</code> tag. Then you can use the Modal like so:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">charset=</span><span class="s">"utf-8"</span><span class="nt">&gt;</span>
<span class="c1">// "Import" the components from Reactstrap</span>
<span class="kd">const</span> <span class="nx">Modal</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">Modal</span><span class="p">.</span><span class="k">default</span><span class="p">;</span>
<span class="c1">// Render a Reactstrap Button element onto root</span>
<span class="nx">ReactDOM</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span>
<span class="nx">React</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="nx">Modal</span><span class="p">,</span>
<span class="p">{</span>
<span class="s1">'show'</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="s1">'closeOnOuterClick'</span><span class="p">:</span> <span class="kc">true</span>
<span class="p">},</span>
<span class="nx">React</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s2">"h1"</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="s2">"Hello"</span><span class="p">)</span>
<span class="p">),</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'root'</span><span class="p">)</span>
<span class="p">);</span>
<span class="nt">&lt;/script&gt;</span>
</code></pre></div></div>
<p>(There are some implementation detail about the <code class="highlighter-rouge">simple-react-modal</code> module in the above code, so don’t be worried if you don’t get everything.)</p>
<h3>The benefits</h3>
<p>Using this method, you can start prototyping by simply copying a HTML file. You don’t need to install Node.js, NPM and all the NPM modules that quickly make your small proof-of-concept page bloat.</p>
<p>Secondly, this method is compatible with the <a href="https://github.com/facebook/react-devtools">React-DevTools</a>. Which is available in both Firefox and Chrome. So debugging is much easier.</p>
<p>Finally, It’s super easy to deploy the program. Simply drop the files into any web server (or use GitHub pages). The server doesn’t even need to run Node and NPM, any pure HTTP server will be sufficient. Other people can also easily download the HTML file and start hacking. This is a very nice way to rapidly prototype complex UIs without spending an extra hour setting up all the build steps (and maybe waste another 2 hour helping the team setting their environment).</p>Thu, 08 Feb 2018 21:39:06 +0000Air Mozilla: Reps Weekly Meeting, 08 Feb 2018https://air.mozilla.org/reps-weekly-meeting-20180208/https://air.mozilla.org/reps-weekly-meeting-20180208/
<p>
<img alt="Reps Weekly Meeting" class="wp-post-image" height="90" src="https://air.cdn.mozilla.net/media/cache/ea/95/ea959e7cca319261380787a7d8f66a94.png" width="160" />
This is a weekly call with some of the Reps to discuss all matters about/affecting Reps and invite Reps to share their work with everyone.
</p>Thu, 08 Feb 2018 16:00:00 +0000Air MozillaAir Mozilla: Mozilla Science Lab February 2018 Bi-monthly Community-Call 20170208https://air.mozilla.org/mozilla-science-lab-february-2018-bi-monthly-community-call-20170208/https://air.mozilla.org/mozilla-science-lab-february-2018-bi-monthly-community-call-20170208/
<p>
<img alt="Mozilla Science Lab February 2018 Bi-monthly Community-Call 20170208" class="wp-post-image" height="90" src="https://air.cdn.mozilla.net/media/cache/40/8e/408eb4dafc585b078c79db2376445c9b.png" width="160" />
Mozilla Science Lab Community Call, February 8
</p>Thu, 08 Feb 2018 16:00:00 +0000Air MozillaMozilla Localization (L10N): L10N Report: February Editionhttp://blog.mozilla.org/l10n/?p=1215https://blog.mozilla.org/l10n/2018/02/07/l10n-report-february-edition/
<h3>Welcome!</h3>
<p>New localizers</p>
<ul>
<li>Kumar has recently joined us to localize in <a href="https://en.wikipedia.org/wiki/Angika_language">Angika</a>. Welcome Kumar!</li>
<li>Francesca has joined Pontoon to localize Firefox in <a href="https://pontoon.mozilla.org/fur/">Friulan</a>. Do you speak the language? Join her!</li>
</ul>
<p>Are you a locale leader and want us to include new members in our upcoming reports? <a href="mailto:l10n-drivers@mozilla.org">Contact us!</a></p>
<h3>New community/locales added</h3>
<ul>
<li>Mixteco Yucuhiti (“meh”) locale was recently added to our l10n repositories and will soon have single-locale builds to test Firefox Android on!</li>
<li>Angika (“anp”) locale was added to Pontoon and will soon start to localize Focus for Android. Welcome!</li>
<li>Friulan (“fur”) has been enabled in Pontoon to localize Firefox, starting from old translations recovered from Pootle.</li>
</ul>
<h3>New content and projects</h3>
<h4>What’s new or coming up in Firefox desktop</h4>
<h5>Migration to FTL (Fluent)</h5>
<p>In the past releases we reached a few small but important milestones for the <a href="http://projectfluent.org/">Fluent project</a>:</p>
<ul>
<li>Firefox 58 was released on January 23 with the first ever Fluent string.</li>
<li>Firefox 59, which will be released on March 13, has 4 more Fluent strings. For this milestone we focused on the migration tools we created to seamlessly port translations from the old format (.properties, .DTD) to Fluent.</li>
</ul>
<p>For Firefox 60, currently in Nightly, we aim to migrate as many strings as possible to Fluent for Firefox Preferences. The process for these migrations is detailed in this <a href="https://groups.google.com/forum/#!msg/mozilla.dev.l10n/vR3YPhalCE4/4XJ6lSEYAwAJ">email to dev-l10n</a>, and there are currently 2 patches almost ready to land, while a larger one for the General pane is in progress.</p>
<p>While Pontoon’s documentation already had a <a href="https://mozilla-l10n.github.io/localizer-documentation/tools/pontoon/ui.html#fluent---ftl-files">section dedicated to Fluent</a>, constantly updated as the interface evolves, our documentation now has a section dedicated to <a href="https://mozilla-l10n.github.io/localizer-documentation/tools/fluent/">Fluent for localizers</a>, explaining the basic syntax and some of the specific features available in Gecko.</p>
<h5>Plural forms</h5>
<p>We already talked about plurals in the <a href="https://blog.mozilla.org/l10n/2017/12/08/l10n-report-december-edition/">December report</a>. The good news is that strings using the wrong number of plural forms are now reported on the <a href="https://l10n.mozilla.org/">l10n dashboard</a> (<a href="https://l10n.mozilla.org/dashboard/compare?run=898125#issue1">example</a>). Here’s a summary of all you need to know about plurals.</p>
<p><b>How plurals work in .properties files</b><br />
Plural forms in Firefox and Firefox for Android are obtained using a hack on top of .properties files (plural forms are separated by a semicolon). For example:</p>
<pre>#1 tab has arrived from #2;#1 tabs have arrived from #2</pre>
<p>English has 2 plural forms, one for singular, and one for all other numbers. The situation is much more complex for other languages, reaching up to 5 or 6 plural forms. In Russian the same string has 3 forms, each one separated from the other by a semicolon:</p>
<pre>С #2 получена #1 вкладка;С #2 получено #1 вкладки;С #2 получено #1 вкладок</pre>
<p>The semicolon is a separator, <b>not a standard punctuation element</b>:</p>
<ul>
<li>You should evaluate and translate each sentence separately. Some locales start the second sentence lowercase because of the semicolon, or with a leading space. Both are errors.</li>
<li>You shouldn’t replace the semicolon with a character from your script, or another punctuation sign (commas, periods). Again, that’s not a punctuation sign, it’s a separator.</li>
</ul>
<p><b>Edge cases</b><br />
Sometimes English only has one form, because the string is used for cases where the number is always bigger than 1.</p>
<pre>;Close #1 tabs</pre>
<p>Note that this string has still two plural forms, the first form (used for case ‘1’, or singular in English) is empty. That’s why the string starts with a semicolon. If your locale only has 1 form, you should drop the leading semicolon.</p>
<p>In other cases, the variable is indicated only in the second form:</p>
<pre>Close one tab;Close #1 tabs</pre>
<p>If your locale only has 1 form, or use the first case for more than ‘1’, use the second sentence as reference for your translation.</p>
<p>There are also cases of “poor” plural forms, where the plural is actually used as a replacement for logic, like “1 vs many”. These are bugs, and should be fixed. For example, <a href="https://searchfox.org/mozilla-central/rev/e06af9c36a73a27864302cd2f829e6200dee8541/browser/locales/en-US/chrome/browser/browser.properties#217">this string</a> was fixed in Firefox 59 (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=658191">bug 658191</a>).</p>
<p><b>Known limitations</b><br />
Plurals form in Gecko are supported only in .properties files, and JavaScript code (not C++).</p>
<p><b>What about devtools?</b><br />
If your locale has more plural forms than English, and you’re copying and pasting English into DevTools strings, the l10n dashboard will show warnings.</p>
<p>You can ignore them, as there’s no way to exclude locales from DevTools, or fix them by creating the expected number of plural forms by copying the English text as many times as needed.</p>
<p><b>Future of plurals</b><br />
With Fluent, <a href="https://mozilla-l10n.github.io/localizer-documentation/tools/fluent/basic_syntax.html#selectors-and-plurals">plurals become much more flexible</a>, allowing locales to create special cases beyond the number of forms expected for their language.</p>
<h4>What’s new or coming up in mobile</h4>
<p>You might have noticed that Focus (iOS/Android) has been on a hiatus since mid-December 2017. That’s because the small <a href="https://blog.mozilla.org/blog/2017/12/20/firefox-is-now-on-amazon-fire-tv-happy-holiday-watching/">mobile team is focusing</a> on <a href="https://www.amazon.com/Mozilla-Firefox-for-Fire-TV/dp/B078B5YMPD">Firefox for Amazon Fire TV</a> development at the moment!</p>
<p>We should be kicking things off again some time in mid-February. A firm date is not confirmed yet, but stay tuned <a href="http://dev-l10n@lists.mozilla.org">on our dev-l10n mailing list</a> for an upcoming announcement!</p>
<p>In the meantime, this means we are not shipping new locales on Focus, and we won’t be generating screenshots until the schedule resumes.</p>
<p>For Firefox on Fire TV – we are still figuring out which locales are officially supported by Amazon, and going to set up the l10n repositories to open it up to Mozilla localizations. There should also a <a href="https://github.com/mozilla-mobile/firefox-tv/issues/408">language switcher in the works</a> very soon, too.</p>
<p>Concerning the Firefox for iOS schedule, it’s almost time to kick-off l10n work for v11! Specific dates will be announced shortly – but expect strings to arrive towards the end of the month. March 29 will be the expected release date.</p>
<p>On the Firefox for Android front, we’ve now released v58. With this new version we bring you two new locales: Nepali (ne-NP) and Bengali from Bangladesh (bn-BD)!</p>
<p>We’re also in the process of adding Tagalog (tl), Khmer (km) and Mixteco Yucuhiti (meh) locales to all-locales to start Fennec single-locale builds.</p>
<h4>What’s new or coming up in web projects</h4>
<ul>
<li>Marketing:
<ul>
<li>Firefox email: The team in charge of the monthly project targeting 6 locales will start following the standard l10n process by email team using bugzilla to communicate the initial requests, Pontoon to host the content, and l10n-driver sending the request through mailing list. Testing emails for verification purpose will be sent to those who worked on the project for the month. The process change has been communicated to the impacted communities. Thanks for responding so well to the change.</li>
<li>Regional single language request will also follow the standard process, moving localization tasks from Google docs to Pontoon. If you are pinged by marketing people for these requests through email or bugzilla, please let the l10n-drivers know. We want to make Pontoon the source of truth, the tool for community collaboration, for future localization references, consistency of terminology usage, for tracking contribution activity.</li>
<li>Mozilla.org has a slow start this year. Most updates have been cleanups and minor fixes. There have been discussions on redesigning the mozilla.org site so the entire site has a unified and modern look from one page to another. This challenges the current way of content delivery, which is at page level. More to share in the upcoming monthly reports.</li>
</ul>
</li>
<li><a href="https://pontoon.mozilla.org/projects/amo-linter/">AMO-Linter</a>, a new project is enabled on Pontoon. This features target add-ons developers. As soon as the information on the feature, the release cycle, the staging server is available, the AMO documentation and Pontoon will be updated accordingly. In the meantime, report bugs by filing <a href="https://github.com/mozilla/addons-linter/issues">an issue</a>.</li>
<li>Firefox Marketplace will be officially shut down on March 30th. Email communication was sent in English. However, a banner with the announcement was placed on the product in top 5 languages.</li>
</ul>
<h4>What’s new or coming up in Foundation projects</h4>
<p>Our 2017 fundraising campaign just finished, but we’re already kicking off this year’s campaign.<br />
One area we want to improve is our communication with donors, so starting in February we will send a monthly donor newsletter. This will help us better communicate how donations are put to use, and build a trust relationship with our supporters.<br />
We will also start raising money much earlier. Our first fundraising email will be a fun one for Valentine’s Day.</p>
<p>A quick update on other localized campaigns:</p>
<ul>
<li>The <a href="https://advocacy.mozilla.org/privacynotincluded">*Privacy not included website </a>is being redesigned to remove the holiday references, and some product reviews might be added soon.</li>
<li>We expect to have some actions this spring around <a href="https://www.eugdpr.org/">GDPR</a> in Europe, but there is no concrete plan yet.</li>
<li>We’ve got some news on the Copyright reform — the JURI Committee will be tentatively voting on March 27th, so we will do some promotion of our <a href="https://www.changecopyright.org/call-now">call tool</a> over the next few weeks.</li>
</ul>
<p>The final countdown has started for the Internet Health Report! The second edition is on its way and should be published in March, this time again in English, German, French and Spanish.</p>
<h4>What’s new or coming up in Pontoon</h4>
<ul>
<li>On February 3, <a href="https://pontoon.mozilla.org/">Pontoon</a> passed 3,000 registered users. Congratulations to <a href="https://pontoon.mozilla.org/contributors/l_ioNE_H8LMZToG2o_HMEEjfmNc/">Balazs Zubak</a> for becoming the 3,000th registered user of Pontoon!</li>
<li>We’re privileged to have <a href="https://github.com/VishalCR7">VishalCR7</a>, <a href="https://github.com/karabellyj">karabellyj</a> and <a href="https://github.com/maiquynhtruong">maiquynhtruong</a> join the Pontoon community of contributors recently. Stay tuned for more details about the work they are doing coming up soon in a blog post!</li>
</ul>
<h3>Friends of the Lion</h3>
<div class="wp-caption alignright" id="attachment_1131"><img alt="" class="wp-image-1131 size-medium" height="232" src="https://blog.mozilla.org/l10n/files/2017/07/2-Lions-01-252x232.png" width="252" /><p class="wp-caption-text">Image by Elio Qoshi</p></div>
<p>Shout out to <a href="https://mozillians.org/u/Alpha/">Adrien G,</a> aka Alpha, for his continuous dedication to French localization on Pontoon and his great progress! He is now an official team member, and we’re happy to have him take on more responsibilities. Congrats!</p>
<p>Know someone in your l10n community who’s been doing a great job and should appear here? Contact on of the l10n-drivers and we’ll make sure they get a shout-out (see list at the bottom)!</p>
<h3>Useful Links</h3>
<ul>
<li><a href="https://lists.mozilla.org/listinfo/dev-l10n">Dev.l10n mailing list</a> and <a href="https://lists.mozilla.org/listinfo/dev-l10n-web">Dev.l10n.web mailing list</a> – where project updates happen. If you are a localizer, then you should be following this</li>
<li><a href="https://www.facebook.com/groups/mozilla.l10n/">Facebook group</a>: it’s new! Come check it out!</li>
<li><a href="https://twitter.com/mozilla_l10n">Twitter</a></li>
<li>Telegram (contact one of the l10n-drivers below so we will add you)</li>
<li><a href="https://blog.mozilla.org/l10n/">L10n blog</a></li>
<li>#l10n irc channel: t<a href="https://wiki.mozilla.org/IRC">his wiki page</a> will help you get set up with IRC. For L10n, we use the #l10n channel for all general discussion. You can also find a list of<a href="https://wiki.mozilla.org/IRC#Channels_in_Other_Languages"> IRC channels in other languages here.</a></li>
</ul>
<h3>Questions? Want to get involved?</h3>
<ul>
<li>If you want to get involved, or have any question about l10n, reach out to:
<ul>
<li><a href="https://mozillians.org/u/delphine/">Delphine</a> – l10n Project Manager for mobile</li>
<li><a href="https://mozillians.org/u/pmo/">Peiying</a> – l10n Project Manager for mozilla.org, marketing, and legal</li>
<li><a href="https://mozillians.org/u/flod/">Francesco Lodolo (flod)</a> – l10n Project Manager for desktop</li>
<li><a href="https://mozillians.org/u/tchevalier/">Théo Chevalier</a> – l10n Project Manager for Mozilla Foundation</li>
<li><a href="https://mozillians.org/u/Pike/">Axel (Pike)</a> – l10n Tech Team Lead</li>
<li><a href="https://mozillians.org/u/stas/">Staś</a> – l20n/FTL tamer</li>
<li><a href="https://mozillians.org/u/gandalf/">Zibi (gandalf)</a> – L10n/Intl Platform Software Engineer</li>
<li><a href="https://mozillians.org/en-US/u/mathjazz/">Matjaž</a> – Pontoon dev</li>
<li><a href="https://mozillians.org/u/adrian/">Adrian</a> – Pontoon dev</li>
<li><a href="https://mozillians.org/u/phlax/">Ryan (phlax)</a> – Pontoon dev</li>
<li><a href="https://mozillians.org/u/gueroJeff/">Jeff Beatty (gueroJeff)</a> – l10n-drivers manager</li>
</ul>
</li>
</ul>
<p>Did you enjoy reading this report? Let us know how we can improve by reaching out to any one of the l10n-drivers listed above.</p>Wed, 07 Feb 2018 21:31:00 +0000DelphineHacks.Mozilla.Org: Forging Better Tools for the Webhttps://hacks.mozilla.org/?p=31894https://hacks.mozilla.org/2018/02/forging-better-tools-for-the-web/
<h3> A Firefox DevTools Retrospective</h3>
<p>2017 was a big year for Firefox DevTools. We updated and refined the UI, refactored three of the panels, squashed countless bugs, and shipped several new features. This work not only provides a faster and better DevTools experience, but lays the groundwork for some exciting new features and improvements for 2018 and beyond. We’re always striving to make tools and features that help developers build websites using the latest technologies and standards, including JavaScript frameworks and, of course, CSS Grid.</p>
<p>To better understand where we’re headed with Firefox Devtools, let’s take a quick look back.</p>
<h4><em>2016</em></h4>
<p>In 2016, the DevTools team kicked off an ambitious initiative to completely transition DevTools away from XUL and Firefox-specific APIs to modern web technologies. One of the first projects to emerge was <a href="http://firefox-dev.tools/debugger.html/" rel="noopener" target="_blank">debugger.html</a>.</p>
<p>Debugger.html is not just an iteration of the old Firefox Debugger. The team threw everything out, created an empty repo, and set out to build a debugger from scratch that utilized reusable React components and a Redux store model.</p>
<p>The benefits of this modern architecture become obvious right away. Everything was more predictable, understandable, and testable. This approach also allows debugger.html to target more than just Firefox. It can target other platforms such as Chrome and Node.</p>
<p>We also shipped a new <a href="https://hacks.mozilla.org/2016/11/new-responsive-design-mode-rdm-lands-in-firefox-dev-tools/" rel="noopener" target="_blank">Responsive Design Mode in 2016</a> that was built using only modern web technologies.</p>
<h4><em>2017</em></h4>
<p>Last year, we continued to build on the work that was started in 2016 by building, and rebuilding parts of Firefox DevTools (and adding new features along the way). As a result, our developer tools are faster and more reliable. We also launched Firefox Quantum, which focused on browser speed, and performance.</p>
<h4>Debugger</h4>
<p>The debugger.html work that started in 2016 <a href="https://hacks.mozilla.org/2017/10/firefox-56-last-stop-before-quantum/" rel="noopener" target="_blank">shipped to all channels with Firefox 56</a>. We also added several new features and improvements, including better search tools, collapsed framework call-stacks, async stepping, and more.</p>
<h4>Console</h4>
<p>Just as with debugger.html, we shipped <a href="https://hacks.mozilla.org/2017/11/new-in-firefox-58-developer-edition/" rel="noopener" target="_blank">a brand-new Firefox console with Firefox Quantum</a>. It has a new UI, and has been completely rewritten using React and Redux. This new console includes several new improvements such as the ability to collapse log groups, and the ability to inspect objects in context.</p>
<h4>Network Monitor</h4>
<p>We also <a href="https://hacks.mozilla.org/2017/06/network-monitor-reloaded/" rel="noopener" target="_blank">shipped a new network monitor</a> to all channels in Firefox 57. This new Network Monitor has a new UI, and is (you guessed it) built with modern web technologies such as React and Redux. It also has a more powerful filter UI, new Netmonitor columns, and more.</p>
<h4>CSS Grid Layout Panel</h4>
<p>Firefox 57 shipped with <a href="https://hacks.mozilla.org/2017/06/new-css-grid-layout-panel-in-firefox-nightly/" rel="noopener" target="_blank">a new CSS Grid Layout Panel</a>. CSS Grid is revolutionizing web design, and we wanted to equip designers and developers with powerful tools for building and inspecting CSS Grid layouts. You can <a href="https://hacks.mozilla.org/2017/10/an-introduction-to-css-grid-layout-part-1/" rel="noopener" target="_blank">read all about the panel features here</a>; highlights include an overlay to visualize the grid, an interactive grid outline, displaying grid area names, and more.</p>
<h4>Photon UI</h4>
<p>We also did <a href="https://hacks.mozilla.org/2017/09/developer-edition-devtools-update-now-with-photon-ui/" rel="noopener" target="_blank">a complete visual refresh of the DevTools</a> themes to coincide with the launch of Firefox Quantum and the new Photon UI. This refresh brings a design that is clean, slick, and easy to read.</p>
<h3>2018 and Beyond</h3>
<p>All of this work has set up an exciting future for Firefox DevTools. By utilizing modern web technologies, we can create, test, and deploy new features at a faster pace than when we were relying on XUL and Firefox-specific APIs.</p>
<p>So what’s next? Without giving too much away, here are just some of the areas we are focusing on:</p>
<h4>Better Tools for Layouts and Design</h4>
<p>This is 2018 and static designs made in a drawing program are being surpassed by more modern tools! Designing in the browser gives us the freedom to experiment, innovate, and build faster. Speaking with hundreds of developers over the past year, we’ve learned that there is a huge desire to bring better design tools to the browser.</p>
<p>We’ve been thrilled by overwhelmingly positive feedback around the CSS Grid Layout Panel and we’ve heard your requests for more tools that help design, build, and inspect layouts.</p>
<blockquote><p>We are making a Firefox Inspector tool to make it easier to write Flexbox code. What do you want it to do the most? What’s the hardest part for you when struggling with Flexbox?<br />
– <a href="https://twitter.com/jensimmons/status/930531359889788928">@jensimmons, 14 Nov 2017</a></p>
<p>I’m so pleased about this reaction to the Firefox Grid Inspector. That was the plan. We’ve just gotten started. More super-useful layout tools are coming in 2018.<br />
– <a href="https://twitter.com/jensimmons/status/934219674526478336">@jensimmons, 24 Nov 2017</a></p></blockquote>
<h4>Better Tools for Frameworks</h4>
<p>2017 was a banner year for JavaScript frameworks such as <a href="https://reactjs.org/" rel="noopener" target="_blank">React</a> and <a href="https://vuejs.org/" rel="noopener" target="_blank">Vue</a>. There are also older favorites such as <a href="https://angular.io/" rel="noopener" target="_blank">Angular</a> and <a href="https://www.emberjs.com/" rel="noopener" target="_blank">Ember</a> that continue to grow and improve. These frameworks are changing the way we build for the web, and we have ideas for how Firefox DevTools can better equip developers who work with frameworks.</p>
<h4>An Even Better UI</h4>
<p>The work on the Firefox DevTools UI will never be finished. We believe there is always room for improvement. We’ll continue to work with the Firefox Developer community to test and ship improvements.</p>
<blockquote><p>New DevTools poll: Which of these three toolbar layouts do you prefer for the Network panel?<br />
– <a href="https://twitter.com/violasong/status/928361002462093312">@violasong</a></p></blockquote>
<h4>More Projects on GitHub</h4>
<p>We tried something new when we started <a href="https://github.com/devtools-html/debugger.html" rel="noopener" target="_blank">building debugger.html</a>. We decided to build the project in GitHub. Not only did we find a number of new contributors, but we received a lot of positive feedback about how easy it was to locate, manage, and work with the code. We will be looking for more opportunities to bring our projects to GitHub this year, so stay tuned.</p>
<h3>Get Involved</h3>
<p>Have an idea? Found a bug? Have a (gasp) complaint? We will be listening very closely to devtools users as we move into 2018 and we want to hear from you. Here are some of the ways you can join our community and get involved:</p>
<h4>Join us on Slack</h4>
<p>You can join our <a href="https://devtools-html-slack.herokuapp.com/">devtools.html Slack community</a>. We also hang out on the #devtools channel on <a href="http://irc.mozilla.org/">irc.mozilla.org</a></p>
<h4>Follow us on Twitter</h4>
<p>We have an official account that you can follow, but you can also follow various team members who will occasionally share ideas and ask for feedback. Follow <a href="https://twitter.com/FirefoxDevTools">@FirefoxDevTools here</a>.</p>
<h3>Contribute</h3>
<p>If you want to get your hand dirty, you can become a contributor:</p>
<p><a href="https://bugzilla.mozilla.org/buglist.cgi?product=Firefox&amp;component=Developer%20Tools&amp;resolution=---">List of open bugs</a><br />
<a href="https://github.com/devtools-html/">GitHub</a></p>
<h4>Download Firefox Developer Edition</h4>
<p><a href="https://www.mozilla.org/firefox/developer/">Firefox Developer Edition</a> is built specifically for developers. It provides early access to all of the great new features we have planned for 2018.</p>
<p>Thank you to everyone who has contributed so far. Your tweets, bug reports, feedback, criticisms, and suggestions matter and mean the world to us. We hope you’ll join us in 2018 as we continue our work to build amazing tools for developers.</p>Wed, 07 Feb 2018 21:26:44 +0000Dustin DriverAir Mozilla: Bugzilla Project Meeting, 07 Feb 2018https://air.mozilla.org/bugzilla-project-meeting-20180207/https://air.mozilla.org/bugzilla-project-meeting-20180207/
<p>
<img alt="Bugzilla Project Meeting" class="wp-post-image" height="90" src="https://air.cdn.mozilla.net/media/cache/c5/50/c550d345896d922304652c2632350f5c.png" width="160" />
The Bugzilla Project Developers meeting.
</p>Wed, 07 Feb 2018 21:00:00 +0000Air MozillaWladimir Palant: Easy Passwords is now PfP: Pain-free Passwordstag:palant.de,2018-02-07:87c0b7bd637338f0d56c50cd41e3eb9b/3089003e7768954a315adb92d371071ahttps://palant.de/2018/02/07/easy-passwords-is-now-pfp-pain-free-passwords
<p>With the important 2.0 milestone I decided to give my Easy Passwords project a more meaningful name. So now it is called PfP: Pain-free Passwords and even has <a href="https://pfp.works/">its own website</a>. And that’s the only thing most people will notice, because the most important changes in this release are well-hidden: the crypto powering the extension got an important upgrade. First of all, the <a href="https://en.wikipedia.org/wiki/PBKDF2">PBKDF2 algorithm</a> for generating passwords was dumped in favor of <a href="https://en.wikipedia.org/wiki/Scrypt">scrypt</a> which is more resistant to brute-force attacks. Also, all metadata written by PfP as well as backups are encrypted now, so that they won’t even leak information about the websites used. Both changes required much consideration and took a while to implement, but now I am way more confident about the crypto than I was <a href="https://palant.de/2016/04/19/introducing-easy-passwords-the-new-best-way-to-juggle-all-those-passwords">back when Easy Passwords 1.0 was released</a>. Finally, there is now an <a href="https://pfp.works/webclient/">online version</a> compiled from the same source code as the extensions and having mostly the same functionality (yes, usability isn’t really great yet, the user interface wasn’t meant for this use case).</p>
<p>Now that the hard stuff is out of the way, what’s next? The plan for the next release is publishing PfP for Microsoft Edge (it’s working already but I need to figure out the packaging), adding sync functionality (all encrypted just like the backups, so that in theory any service where you can upload files could be used) and importing backups created with a different master password (important as a migration path when you change your master password). After that I want to look into creating an Android client as well as a Node-based command line interface. These new clients had to be pushed back because they are most useful with sync functionality available.</p>Wed, 07 Feb 2018 19:28:06 +0000Wladimir PalantAir Mozilla: Weekly SUMO Community Meeting, 07 Feb 2018https://air.mozilla.org/weekly-sumo-community-meeting-20180207/https://air.mozilla.org/weekly-sumo-community-meeting-20180207/
<p>
<img alt="Weekly SUMO Community Meeting" class="wp-post-image" height="90" src="https://air.cdn.mozilla.net/media/cache/4c/b1/4cb1b015e6a393e53dfc196726ec2561.png" width="160" />
This is the SUMO weekly call
</p>Wed, 07 Feb 2018 17:00:00 +0000Air MozillaThe Mozilla Blog: Announcing the Reality Redrawn Challenge Winners!https://blog.mozilla.org/?p=11229https://blog.mozilla.org/blog/2018/02/07/announcing-reality-redrawn-challenge-winners/
<p>I’m delighted to announce the winners of Mozilla’s Reality Redrawn Challenge after my fellow judges and I received entries from around the globe. Since we <a href="https://blog.mozilla.org/blog/2017/12/05/woke-up-and-thought-you-were-in-a-different-reality/">issued the challenge</a> just two months ago we have been astonished by the quality and imagination behind proposals that use mixed reality and other media to make the power of misinformation and its potential impacts visible and visceral. </p>
<p>If you have tried to imagine the impact of fake news – even what it smells like – when it touches your world, I hope you will come to experience the Reality Redrawn exhibit at the <a href="https://www.thetech.org/">Tech Museum of Innovation</a> in San Jose. Our opening night runs from 5-9pm on May 17th and free tickets are available <a href="https://www.eventbrite.com/e/mozilla-presents-the-reality-redrawn-exhibit-opening-night-event-tickets-42927531402">here</a>. Keep an eye on Twitter @mozilla with the hashtag #RealityRedrawn for more details in the coming weeks. After opening night you can experience the exhibit in normal daily museum hours for a limited engagement of two weeks, 10am-5pm. We will be looking to bring the winning entries to life also for those who are not in the Bay Area.</p>
<p>The winner of our grand prize of $15,000 is Yosun Chang from San Francisco with Bubble Chaos. Yosun has won many competitions including the Salesforce Dreamforce 2011 Hackathon, Microsoft Build 2016 Hackathon and TechCrunch Disrupt 2016 Hackathon. She will use augmented reality and virtual reality to create an experience that allows the user to interact with misinformation in a creative new way. </p>
<p>Yosun says of her entry: “We iPhoneX face track a user’s face to puppeteer their avatar, then bot and VR crowdsource lipreading that avatar to form political sides. This powers the visuals of a global macroscopic view showing thousands of nodes transmitting to create misinformation. We present also the visceral version where the user can try to “echo” their scented-colored bubble in a “bubble chamber” to make the room smell like their scent with multiple pivoting SensaBubble machines.”</p>
<p>Our second prize joint semi-finalist is Stu Campbell (aka Sutu) from Roeburne in Western Australia. Sutu will receive $7,500 to complete the creation of his entry FAKING NEWS. He is known for ‘Nawlz’, a 24 episode interactive cyberpunk comic book series created for web and iPad. In 2016 he was commissioned by Marvel and Google to create Tilt Brush Virtual Reality paintings. He was also the feature subject of the 2014 documentary, ‘Cyber Dreaming’.</p>
<p>As Sutu explains: “The front page of a newspaper will be reprinted in a large format and mounted to the museum wall. Visitors will also find physical copies of the paper in the museum space. Visitors will be encouraged to download our EyeJack Augmented Reality app and then hold their devices over the paper to see the story augment in real time. Small fake news bots will animate across the page, rearranging and deleting words and inserting news words and images. The audience then has the option to share the new augmented news to their own social media channels, thus perpetuating its reach.”</p>
<p>Mario Ezekiel Hernandez from Austin also receives $7,500 to complete his entry: Where You Stand. Mario graduated from Texas State University in 2017 with a degree in Applied Mathematics. He currently works as a data analyst and is a member of the interactive media arts collective, vûrv.</p>
<p>Mario’s entry uses TouchDesigner, Python, R, OpenCV, web cameras, projectors, and a mac mini. Mario says of his entry: “Our solution seeks to shine a light on the voices of policymakers and allow participants to freely explore the content that is being promoted by their legislative representatives. The piece dynamically reacts to actor locations. As they move along the length of the piece tweets from each legislator are revealed and hidden. To highlight the polarization we group the legislators by party alignment so that the most partisan legislators are located at the far ends of the piece. As participants move away from the middle in either direction, they will see more tweets from increasingly partisan legislators.”</p>
<p>Emily Saltz is a UX Designer from Bloomberg LP and will be traveling from New York with her entry Filter Bubble Roulette, after receiving prize money of $5,000. Previously she was UX and Content Strategist at Pop Up Archive, an automatic speech recognition service and API acquired by Apple. </p>
<p>Emily says of her entry: “This social webVR platform plays into each user’s curiosity to peek into other social media filter bubbles, using content pulled from social media as conversational probes. It will enable immersive connection people across diverse social and political networks. The project is based on the hypotheses that 1) users are curious to peek into the social media universes of others, 2) it’s harder to be a troll when you’re immersed in someone else’s 3D space, and 3) viewing another person’s filter bubble in context of their other interests will enable more reflection and empathy between groups.”</p>
<p>Rahul Bhargava is a researcher and technologist specializing in civic technology and data literacy at the MIT Center for Civic Media. There he leads technical development on projects ranging from interfaces for quantitative news analysis, to platforms for crowd-sourced sensing. Based in Boston, he also won $5,000 to create his entry Gobo: understanding social media algorithms.</p>
<p>Rahul says of his entry: “The public lacks a basic understanding of the algorithm-driven nature of most online platforms. In parallel, technology companies generally place blind trust in algorithms as “neutral” actors in content promotion. Our idea tackles this perfect storm with a card-driven interactive piece, where social media content is scored with a variety of algorithms and prompts to discuss how those can drive content filtering and promotion. Visitors are engaged to use these scores as inputs to construct their own meta-algorithm, deciding whether things like “gender” detection, “rudeness” ranking, or “sentiment” analysis would drive which content they want to see.”</p>
<p>The Reality Redrawn Challenge is part of the Mozilla Information Trust Initiative <a href="https://blog.mozilla.org/blog/2017/08/08/mozilla-information-trust-initiative-building-movement-fight-misinformation-online/">announced last year</a> to build a movement to fight misinformation online. The initiative aims to stimulate work towards this goal on products, research, literacy and creative interventions. </p>
<p>The post <a href="https://blog.mozilla.org/blog/2018/02/07/announcing-reality-redrawn-challenge-winners/" rel="nofollow">Announcing the Reality Redrawn Challenge Winners!</a> appeared first on <a href="https://blog.mozilla.org" rel="nofollow">The Mozilla Blog</a>.</p>Wed, 07 Feb 2018 16:01:39 +0000Katharina BorchertMozilla Thunderbird: What Thunderbird Learned at FOSDEMhttp://blog.mozilla.org/thunderbird/?p=745https://blog.mozilla.org/thunderbird/2018/02/what-thunderbird-learned-at-fosdem/
<p>Hello everyone! I’m writing this following a visit to Brussels this past weekend to the Free and Open Source Software conference called FOSDEM. As far as I know it is one of the largest, if not the largest FOSS conference in Europe. It proved to be a great opportunity to discuss Thunderbird with a wide range of contributors, users, and interested developers – and the feedback I received at the event was fantastic (and helpful)!</p>
<p>First, some background, the Thunderbird team was stationed in the Mozilla booth, on the second floor of building K. We were next to the Apache Software Foundation and the Kopano Collaborative software booths (the Kopano folks gave us candy with “Mozilla” printed on it – very cool). We had hundreds of people stop by the booth and I got to ask a bunch of them about what they thought of Thunderbird. Below are some insights I gained from talking to the FOSDEM attendees.</p>
<h3><strong>Feedback from FOSDEM</strong></h3>
<p><strong>1. I thought the project was dead. What’s the plan for the future of Thunderbird?</strong></p>
<p>This was the number one thing I heard repeatedly throughout the conference. This is not surprising as, while the project has remained active following its split from Mozilla corp, it has not been seen to push the boundaries or made a lot of noise about its own initiatives. We, as the Thunderbird community, should be planning on the future and what that looks like – once we have a concrete roadmap, we should share that with the world to solicit interest and enthusiasm.</p>
<p>For fear of this question being misunderstood, this was never asked with malevolent intent or in a dismissive way (as far as I could tell). Most of the people who commented on the project being dead were generally interested in using Thunderbird (or were still), but didn’t realize anyone was actively doing development. I got many stories where people shared their relief saying “I was planning on having to move to something else for a mail client, but now that I’ve seen the project making plans, I’m going to stay with it.”</p>
<p>Currently, we have a lot to talk about regarding the future of Thunderbird. We have made new hires (yours truly included), <a href="https://blog.mozilla.org/thunderbird/2018/01/were-hiring-a-developer-to-work-on-thunderbird-full-time/">we are hiring a developer</a> to work on various parts of the project, and we are working with organizations like <a href="https://www.monterail.com/blog/thunderbird-new-interface-redesign-survey">Monterail in order to get feedback on the interface</a>. With the upcoming Thunderbird Council elections, the Community will get an opportunity to shape the leadership of the project as well.</p>
<p><strong>2. I would like to see a mobile app.</strong></p>
<p>The second most prevalent thing expressed to me at FOSDEM was the desire for a Thunderbird mobile app. When I asked what that might look like the answers were uniformly along the lines of: “There is not a really good, open source, Email client on mobile. Thunderbird seems like a great project with the expertise to solve that.”</p>
<p><strong>3. Where’s the forum?</strong></p>
<p>Heard this a few times and was surprised out how adamant the people asking were. They pointed out that they were Thunderbird users, but weren’t really into mailing lists. I had it iterated to me a handful of times that Discourse allows you to respond via Email or the website. As a result I have begun working on setting something up.</p>
<p>The biggest barrier I see to making a forum a core part of the community effort is getting buy-in from MOST of the contributors to the project currently. So, over the next week I’m going to try and get an idea of who is interested in participating and who is opposed.</p>
<p><strong>4. I want built-in Encryption</strong></p>
<p>This was a frequent request asked for in two forms, repeatedly. First, “How can I encrypt my Thunderbird Email?” and second, “Can you make encryption a default feature?” – the frequency with which this was asked indicates that this is important to this segment of our users (open source, technical).</p>
<p>To those who are curious as to how to encrypt your mail currently – the answer is you may <a href="https://www.enigmail.net/index.php/en/">use the Enigmail extension</a>. In the future, we may be able to make this easier by having it built-in to Thunderbird and making it possible to enable in the settings. But that is a discussion that the community and developers need to explore further.</p>
<h3><strong>Final Thoughts</strong></h3>
<p>In closing, I heard a great many things beyond those four key points above – but many were thoughts on specific bugs people experienced (<a href="https://bugzilla.mozilla.org/describecomponents.cgi?product=Thunderbird">you can file bugs here</a>), or just comments on how people used mostly webmail these days. On that second point, I heard that so frequently that I began to wonder what more we could offer as a project that would provide added value to users over what things like GMail, Inbox, and Outlook365 were offering.</p>
<p>All-around FOSDEM was a great event, met great people, heard amazing talks, and got to spread the good word of Thunderbird. Would love to hear the community’s ideas on what they think of what I heard, that means you, so please leave a comment below.</p>Wed, 07 Feb 2018 14:23:37 +0000Ryan SipesMozilla Marketing Engineering & Ops Blog: MDN Changelog for January 2018https://mozilla.github.io/meao/2018/02/07/mdn-changeloghttps://mozilla.github.io/meao/2018/02/07/mdn-changelog/
<p>Here’s what happened in January to the
<a href="https://github.com/mdn/">code, data, and tools</a>
that support
<a href="https://developer.mozilla.org">MDN Web Docs</a>:</p>
<ul>
<li><a href="https://mozilla.github.io/meao/atom.xml#css-bcd-jan-18">Completed CSS compatibility data migration and more</a></li>
<li><a href="https://mozilla.github.io/meao/atom.xml#lang-cookie-jan-18">Shipped a new method for declaring language preference</a></li>
<li><a href="https://mozilla.github.io/meao/atom.xml#mdn-perf-jan-18">Increased availability of MDN</a></li>
<li><a href="https://mozilla.github.io/meao/atom.xml#tweaks-jan-18">Shipped tweaks and fixes</a>
by merging 326 pull requests,
including 67 pull requests
from 27 new contributors.</li>
</ul>
<p>Here’s the plan for February:</p>
<ul>
<li><a href="https://mozilla.github.io/meao/atom.xml#continue-jan-18">Continue development projects</a></li>
</ul>
<h3>Done in January</h3>
<h4><a name="css-bcd-jan-18">Completed CSS Compatibility Data Migration and More</a></h4>
<p>Thanks to <a href="https://github.com/ddbeck">Daniel D. Beck</a> and his
<a href="https://github.com/mdn/browser-compat-data/pulls?utf8=%E2%9C%93&amp;q=is%3Apr+is%3Aclosed+merged%3A%222018-01-01..2018-01-31%22+author%3Addbeck">83 Pull Requests</a>,
the CSS compatibility data is migrated to the
<a href="https://github.com/mdn/browser-compat-data">browser-compat-data</a> repository.
This finishes Daniel’s current contract, and we hope to get his help again
soon.</p>
<p>The newly announced
<a href="https://hacks.mozilla.org/2018/01/introducing-the-mdn-product-advisory-board/">MDN Product Advisory
Board</a>
supports the Browser Compatibility Data project, and members are working to
migrate more data. In January, we saw an increase in contributions, many from
first-time contributors. The migration work jumped from 39% to 43% complete in
January. See the <a href="https://github.com/mdn/browser-compat-data/blob/master/CONTRIBUTING.md">contribution
guide</a>
to learn how to help.</p>
<p>On January 23, we turned on the
<a href="https://discourse.mozilla.org/t/new-mdn-browser-compatibility-tables/24747">new browser compatability tables</a>
for all users. The new presentation provides a good overview of feature support
across desktop and mobile browsers, as well as JavaScript run-time environments
like Node.js, while still letting implementors dive into the details.</p>
<p><a href="http://florianscholz.com/">Florian Scholz</a> promoted the project with a
<a href="https://hacks.mozilla.org/2018/02/mdn-browser-compatibility-data/">blog post</a>,
and highlighted the
<a href="https://addons.mozilla.org/en-US/firefox/addon/compat-report/">compat-report addon</a>
by <a href="https://twitter.com/eduardoboucas">Eduardo Bouças</a>
that uses the data to highlight compatibility issues in a developer tools tab.
Florian also gave
<a href="https://video.fosdem.org/2018/UA2.118/">a talk about the project</a>
on February 3 at
<a href="https://fosdem.org/2018/schedule/event/mozilla_mdn_browser_compat_data_project/">FOSDEM 18</a>.
We’re excited to tell people about this new resource, and see what people will
do with this data.</p>
<p><img alt="compat-report" src="https://mozilla.github.io/meao/public/images/kuma/2018-01-compat-report.png" title="Compatibility report on MozMEAO" /></p>
<h4><a name="lang-cookie-jan-18">Shipped a New Method for Declaring Language Preference</a></h4>
<p>If you use the language switcher on MDN, you’ll now be asked if you want to
always view the site in that language. This was added by
<a href="https://github.com/safwanrahman">Safwan Rahman</a> in
<a href="https://github.com/mozilla/kuma/pull/4321">PR 4321</a>.</p>
<p><img alt="language-switcher" src="https://mozilla.github.io/meao/public/images/kuma/2018-01-lang-cookie.png" title="Language preference switcher dialog" /></p>
<p>This preference goes into effect for our “locale-less” URLs. If you access
<a href="https://developer.mozilla.org/docs/Web/HTML">https://developer.mozilla.org/docs/Web/HTML</a>, MDN uses your browser’s
preferred language, as set by the
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language">Accept-Language</a>
header. If it is set to <code class="highlighter-rouge">Accept-Language: en-US,en;q=0.5</code>, then you’ll get
the English page at
<a href="https://developer.mozilla.org/en-US/docs/Web/HTML">https://developer.mozilla.org/en-US/docs/Web/HTML</a>, while
<code class="highlighter-rouge">Accept-Language: de-CH</code> will send you to the German page at
<a href="https://developer.mozilla.org/de/docs/Web/HTML">https://developer.mozilla.org/de/docs/Web/HTML</a>.
If you’ve set a preference with this new dialog box, the
<code class="highlighter-rouge">Accept-Language</code> header will be ignored and you’ll get your preferred
language for MDN.</p>
<p>This is useful for MDN visitors who like to browse the web in their native
language, but read MDN in English, but it doesn’t fix the issue entirely.
If a search engine thinks you prefer German, for instance, it will pick the
German translations of MDN pages, and send you to
<a href="https://developer.mozilla.org/de/docs/Web/HTML">https://developer.mozilla.org/de/docs/Web/HTML</a>. MDN respects the link and
shows the German page, and the new language preference is not used.</p>
<p>We hope this makes MDN a little easier to use, but more will be needed to
satisfy those who get the “wrong” page. I’m not convinced there is a solution
that will work for everyone. I’ve suggested a web extension in
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1432826">bug 1432826</a>, to allow
configurable redirects, but it is unclear if this is the right solution.
We’ll keep thinking about translations, and adjusting to visitors’ preferences.</p>
<h4><a name="mdn-perf-jan-18">Increased Availability of MDN</a></h4>
<p>MDN easily serves millions of visitors a month, but struggles under some
traffic patterns, such as a single visitor requesting every page on the site.
We continue to make MDN more reliable despite these traffic spikes, using
several different strategies.</p>
<p>The most direct method is to limit the number of requests. We’ve updated our
rate limiting to return the HTTP 429 “Too Many Requests” code
(<a href="https://github.com/mozilla/kuma/pull/4614">PR 4614</a>), to more clearly
communicate when a client hits these limits.
<a href="https://github.com/metadave">Dave Parfitt</a> automated bans for users making
thousands of requests a minute, which is much more than legitimate scrapers.</p>
<p>Another strategy is to reduce the database load for each request, so that high
traffic doesn’t slow down the database and all the page views. We’re reducing
database usage by changing how async processes store state
(<a href="https://github.com/mozilla/kuma/pull/4615">PR 4615</a>) and using long-lasting
database connections to reduce time spent establishing per-request connections
(<a href="https://github.com/mozilla/kuma/pull/4644">PR 4644</a>).</p>
<p><a href="https://github.com/safwanrahman">Safwan Rahman</a> took a close look at the
database usage for wiki pages, and made several changes to reduce both the
number of queries and the size of the data transmitted from the database
(<a href="https://github.com/mozilla/kuma/pull/4630">PR 4630</a>). This last change has
significantly reduced the network traffic to the database.</p>
<p><img alt="network-traffic-drop" src="https://mozilla.github.io/meao/public/images/kuma/2018-01-network-traffic-drop.png" title="Network traffic dropped afer shipping PR 4630" />
<img alt="response-time" src="https://mozilla.github.io/meao/public/images/kuma/2018-01-response-time.png" title="New Relic response time after shipping PR 4630" /></p>
<p>All of these add up
to a 10% to 15% improvement in server response time from December’s
performance.</p>
<p><a href="https://github.com/escattone">Ryan Johnson</a> continued work on the long-term
solution, to serve MDN content from a CDN. This requires getting our caching
headers just right
(<a href="https://github.com/mozilla/kuma/pull/4638">PR 4638</a>).
We hope to start shipping this in February. At that point, a high-traffic user
may still slow down the servers, but most people will quickly get their content
from the CDN instead.</p>
<h4><a name="tweaks-jan-18">Shipped Tweaks and Fixes</a></h4>
<p>There were 326 PRs merged in January:</p>
<ul>
<li><a href="https://github.com/mdn/browser-compat-data/pulls?page=1&amp;q=is:pr+is:closed+merged:">156 mdn/browser-compat-data PRs</a></li>
<li><a href="https://github.com/mdn/interactive-examples/pulls?page=1&amp;q=is:pr+is:closed+merged:">75 mdn/interactive-examples PRs</a></li>
<li><a href="https://github.com/mozilla/kuma/pulls?page=1&amp;q=is:pr+is:closed+merged:">44 mozilla/kuma PRs</a></li>
<li><a href="https://github.com/mdn/kumascript/pulls?page=1&amp;q=is:pr+is:closed+merged:">27 mdn/kumascript PRs</a></li>
<li><a href="https://github.com/mozmeao/infra/pulls?page=1&amp;q=is:pr+is:closed+merged:">19 mozmeao/infra PRs</a></li>
<li><a href="https://github.com/mdn/data/pulls?page=1&amp;q=is:pr+is:closed+merged:">5 mdn/data PRs</a></li>
</ul>
<p>67 of these were from first-time contributors:</p>
<ul>
<li>Update JS grammar compat data for Chrome (trailing commas for functions)
(<a href="https://github.com/mdn/browser-compat-data/pull/732">BCD PR 732</a>),
from
<a href="https://github.com/odony">Olivier Dony</a>.</li>
<li>Add classes compatibility with respect to Node.js
(<a href="https://github.com/mdn/browser-compat-data/pull/746">BCD PR 746</a>),
from
<a href="https://github.com/madarche">Marc-Aurèle DARCHE</a>.</li>
<li>Add compat data for CanvasCaptureMediaStream
(<a href="https://github.com/mdn/browser-compat-data/pull/829">PR 829</a>),
CanvasGradient
(<a href="https://github.com/mdn/browser-compat-data/pull/830">PR 830</a>),
CanvasPattern
(<a href="https://github.com/mdn/browser-compat-data/pull/832">PR 832</a>),
CanvasRenderingContext2D
(<a href="https://github.com/mdn/browser-compat-data/pull/851">PR 851</a>),
HTMLCanvasElement
(<a href="https://github.com/mdn/browser-compat-data/pull/880">PR 880</a>),
ImageBitmap
(<a href="https://github.com/mdn/browser-compat-data/pull/883">PR 883</a>),
ImageBitmapRenderingContext
(<a href="https://github.com/mdn/browser-compat-data/pull/885">PR 885</a>),
ImageData
(<a href="https://github.com/mdn/browser-compat-data/pull/891">PR 891</a>),
Path2D
(<a href="https://github.com/mdn/browser-compat-data/pull/893">PR 893</a>),
and
TextMetrics
(<a href="https://github.com/mdn/browser-compat-data/pull/894">PR 894</a>),
from
<a href="https://github.com/maboa">Mark Boas</a>
(first contributions to BCD).</li>
<li>Fix “RGB” typo to “RGBA” for the hex RGBA spec
(<a href="https://github.com/mdn/browser-compat-data/pull/835">BCD PR 835</a>),
from
<a href="https://github.com/ubershmekel">Yuval Greenfield</a>.</li>
<li>Update text-decoration-skip.json
(<a href="https://github.com/mdn/browser-compat-data/pull/836">BCD PR 836</a>),
from
<a href="https://github.com/paulirish">Paul Irish</a>.</li>
<li>Add data for Samsung Internet to font-face.json
(<a href="https://github.com/mdn/browser-compat-data/pull/840">BCD PR 840</a>),
from
<a href="https://github.com/AdaRoseCannon">Ada Rose Cannon</a>.</li>
<li>Fix a typo in css.properties.justify-content
(<a href="https://github.com/mdn/browser-compat-data/pull/844">BCD PR 844</a>),
from
<a href="https://github.com/yume-chan">Simon Chan</a>.</li>
<li>Edge doesn’t currently support requestBody for webRequest
(<a href="https://github.com/mdn/browser-compat-data/pull/860">BCD PR 860</a>),
from
<a href="https://github.com/durbin">Neil Durbin</a>.</li>
<li>IE11 doesn’t support Map(iterable) constructor
(<a href="https://github.com/mdn/browser-compat-data/pull/874">BCD PR 874</a>),
from
<a href="https://github.com/Jeff-Mott-OR">Jeff-Mott-OR</a>.</li>
<li>Update break-word
(<a href="https://github.com/mdn/browser-compat-data/pull/882">BCD PR 882</a>,
<a href="https://github.com/mdn/data/pull/164">Data PR 164</a>, and
<a href="https://github.com/mdn/interactive-examples/pull/440">Interactive Examples PR 440</a>),
from
<a href="https://github.com/CShepartd">CShepartd</a>.</li>
<li>nodejs ES module support flag info
(<a href="https://github.com/mdn/browser-compat-data/pull/903">BCD PR 903</a>),
from
<a href="https://github.com/slikts">slikts</a>.</li>
<li>Fix parameter ordering Math.atan2 example
(<a href="https://github.com/mdn/interactive-examples/pull/385">Interactive Examples PR 385</a>),
from
<a href="https://github.com/Anemy">Rhys Howell</a>.</li>
<li>Fixed the demo titles
(<a href="https://github.com/mdn/interactive-examples/pull/401">Interactive Examples PR 401</a>),
from
<a href="https://github.com/7ayushgupta">Ayush Gupta</a>.</li>
<li>Allow an empty commit for travis deploy
(<a href="https://github.com/mdn/interactive-examples/pull/410">PR 410</a>),
from
<a href="https://github.com/jwhitlock">me</a>
(first contribution to Interactive Examples).</li>
<li>Add demo for text-decoration-skip-ink
(<a href="https://github.com/mdn/interactive-examples/pull/411">Interactive Examples PR 411</a>),
from
<a href="https://github.com/paulirish">Paul Irish</a>.</li>
<li>Typo fix
(<a href="https://github.com/mdn/interactive-examples/pull/424">PR 424</a>),
Fix URL and missing comma
(<a href="https://github.com/mdn/interactive-examples/pull/446">PR 446</a>),
Fix clipboard target ids
(<a href="https://github.com/mdn/interactive-examples/pull/447">PR 447</a>),
Add <code class="highlighter-rouge">border-width</code> example
(<a href="https://github.com/mdn/interactive-examples/pull/448">PR 448</a>),
Add <code class="highlighter-rouge">border-color</code> example
(<a href="https://github.com/mdn/interactive-examples/pull/465">PR 465</a>),
Add <code class="highlighter-rouge">overflow-wrap</code> example
(<a href="https://github.com/mdn/interactive-examples/pull/472">PR 472</a>),
Add <code class="highlighter-rouge">&lt;angle&gt;</code> example
(<a href="https://github.com/mdn/interactive-examples/pull/473">PR 473</a>),
Update <code class="highlighter-rouge">border-style</code> example
(<a href="https://github.com/mdn/interactive-examples/pull/474">PR 474</a>),
Add <code class="highlighter-rouge">text-transform</code> example
(<a href="https://github.com/mdn/interactive-examples/pull/475">PR 475</a>),
Add <code class="highlighter-rouge">border-*-width</code> examples
(<a href="https://github.com/mdn/interactive-examples/pull/499">PR 499</a>),
Add <code class="highlighter-rouge">border-*-color</code> examples
(<a href="https://github.com/mdn/interactive-examples/pull/501">PR 501</a>),
Add <code class="highlighter-rouge">border-*-style</code> examples
(<a href="https://github.com/mdn/interactive-examples/pull/504">PR 504</a>),
Add <code class="highlighter-rouge">border</code> examples
(<a href="https://github.com/mdn/interactive-examples/pull/511">PR 511</a>),
Add <code class="highlighter-rouge">overflow-*</code> examples
(<a href="https://github.com/mdn/interactive-examples/pull/513">PR 513</a>),
Add/update <code class="highlighter-rouge">background-position-*</code> examples
(<a href="https://github.com/mdn/interactive-examples/pull/514">PR 514</a>),
and
Add <code class="highlighter-rouge">text-decoration-color</code> example
(<a href="https://github.com/mdn/interactive-examples/pull/516">PR 516</a>),
from
<a href="https://github.com/mfluehr">mfluehr</a>
(first contributions to Interactive Examples).</li>
<li>Add demo for Array.toString() and Array.unshift(), Fixes #421 and #422
(<a href="https://github.com/mdn/interactive-examples/pull/427">PR 427</a>),
Add demo for Array.prototypes Fixes #420, #419
(<a href="https://github.com/mdn/interactive-examples/pull/435">PR 435</a>),
and
Add demo for Array.prototypes Fixes #417 and #416
(<a href="https://github.com/mdn/interactive-examples/pull/439">PR 439</a>),
to Interactive Examples from
<a href="https://github.com/maddhruv">Dhruv Jain</a>.</li>
<li>console.log support for multiple arguments
(<a href="https://github.com/mdn/interactive-examples/pull/433">Interactive Examples PR 433</a>),
from
<a href="https://github.com/qwIvan">Ivan Ng</a>.</li>
<li>Indents the break statements
(<a href="https://github.com/mdn/interactive-examples/pull/437">Interactive Examples PR 437</a>),
from
<a href="https://github.com/mlissner">Mike Lissner</a>.</li>
<li>Enhance formatObject to support formatting actual object
(<a href="https://github.com/mdn/interactive-examples/pull/451">PR 451</a>),
Add few examples
(<a href="https://github.com/mdn/interactive-examples/pull/458">PR 458</a>),
Add .shorter css class for shorter JS examples
(<a href="https://github.com/mdn/interactive-examples/pull/462">PR 462</a>),
and
Reorganize live-examples folder
(<a href="https://github.com/mdn/interactive-examples/pull/500">PR 500</a>),
to Interactive Examples from
<a href="https://github.com/kenrick95">Kenrick</a>.</li>
<li>Add interactive demo for Array.forEach(). Fixes #413
(<a href="https://github.com/mdn/interactive-examples/pull/452">PR 452</a>),
and
Add UTC set examples for Minutes,Milliseconds and Seconds
(<a href="https://github.com/mdn/interactive-examples/pull/459">PR 459</a>),
to Interactive Examples from
<a href="https://github.com/suknuk">Raymond Lochner</a>.</li>
<li>Added examples for Array.prototype.reverse and Array.prototype.keys
(<a href="https://github.com/mdn/interactive-examples/pull/460">Interactive Examples PR 460</a>),
from
<a href="https://github.com/diablero13">Anton Boyko</a>.</li>
<li>Add line-height CSS example
(<a href="https://github.com/mdn/interactive-examples/pull/485">PR 485</a>),
Add text-decoration-line CSS example
(<a href="https://github.com/mdn/interactive-examples/pull/487">PR 487</a>),
Fixed some (all?) <code class="highlighter-rouge">data-clipboard-target</code> for CSS examples
(<a href="https://github.com/mdn/interactive-examples/pull/488">PR 488</a>),
Add text-decoration-style CSS example
(<a href="https://github.com/mdn/interactive-examples/pull/490">PR 490</a>),
Dynamically get clipboard button targets
(<a href="https://github.com/mdn/interactive-examples/pull/491">PR 491</a>),
and
Remove data-clipboard-target attribute
(<a href="https://github.com/mdn/interactive-examples/pull/508">PR 508</a>),
to Interactive Examples from
<a href="https://github.com/danielhickman">Daniel Hickman</a>.</li>
<li>Fixed l10n-aware link to New_Compatibility_Tables_Beta
(<a href="https://github.com/mozilla/kuma/pull/4609">PR 4609</a>),
and
Fixed l10n-aware link to Troubleshooting article
(<a href="https://github.com/mozilla/kuma/pull/4613">PR 4613</a>),
from
<a href="https://github.com/asmforce">Віталій Крутько</a>
(first contributions to Kuma).</li>
<li>Update LearnSidebar.ejs with French Translation
(<a href="https://github.com/mdn/kumascript/pull/550">KumaScript PR 550</a>),
from
<a href="https://github.com/Ilphrin">Kevin “Ilphrin” Pellet</a>.</li>
<li>Fix typo in French translation for Spec2 macro
(<a href="https://github.com/mdn/kumascript/pull/556">KumaScript PR 556</a>),
from
<a href="https://github.com/Koroeskohr">Victor Viale</a>.</li>
<li>Merge specification status, names and urls into a single source
(<a href="https://github.com/mdn/kumascript/pull/557">PR 557</a>),
and
Update statuses and URLs of a number of W3C specs
(<a href="https://github.com/mdn/kumascript/pull/565">PR 565</a>),
to KumaScript from
<a href="https://github.com/dontcallmedom">Dominique Hazael-Massieux</a>.</li>
<li>Remove legacy <code class="highlighter-rouge">autocomplete</code> and <code class="highlighter-rouge">autocompleteerror</code> events
(<a href="https://github.com/mdn/kumascript/pull/569">PR 569</a>),
from
<a href="https://github.com/mnoorenberghe">Matt N.</a>
(first contribution to KumaScript).</li>
</ul>
<p>Other significant PRs:</p>
<ul>
<li>Fix issue 546: Allow multiple flags (rename flag to flags)
(<a href="https://github.com/mdn/browser-compat-data/pull/701">BCD PR 701</a> and
<a href="https://github.com/mdn/kumascript/pull/438">KumaScript PR 438</a>),
from
<a href="https://github.com/Elchi3">Florian Scholz</a>.</li>
<li>SharedArrayBuffer now unsupported to mitigate Spectre attack
(<a href="https://github.com/mdn/browser-compat-data/pull/789">BCD PR 789</a>),
from
<a href="https://github.com/Elchi3">Florian Scholz</a>.</li>
<li>Add safari_ios validation
(<a href="https://github.com/mdn/browser-compat-data/pull/831">BCD PR 831</a>),
from
<a href="https://github.com/Elchi3">Florian Scholz</a>.</li>
<li>Refactor browser data
(<a href="https://github.com/mdn/browser-compat-data/pull/834">BCD PR 834</a>),
from
<a href="https://github.com/Elchi3">Florian Scholz</a>.</li>
<li>Further restrict identifiers
(<a href="https://github.com/mdn/browser-compat-data/pull/915">BCD PR 915</a>),
from
<a href="https://github.com/Elchi3">Florian Scholz</a>.</li>
<li>Adds config for welcome bot
(<a href="https://github.com/mdn/interactive-examples/pull/407">Interactive Examples PR 407</a>),
from
<a href="https://github.com/schalkneethling">Schalk Neethling</a>.</li>
<li>Disables interactive examples for the currently disabled SharedArrayBuffer
(<a href="https://github.com/mdn/interactive-examples/pull/430">Interactive Examples PR 430</a>),
from
<a href="https://github.com/schalkneethling">Schalk Neethling</a>.</li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1308322">Bug 1308322</a>:
Upgrade to selenium 3.x
(<a href="https://github.com/mozilla/kuma/pull/4195">Kuma PR 4195</a>),
from
<a href="https://github.com/jwhitlock">me</a>.</li>
<li>Add icons in case of support ranges
(<a href="https://github.com/mdn/kumascript/pull/548">KumaScript PR 548</a>),
from
<a href="https://github.com/Elchi3">Florian Scholz</a>.</li>
</ul>
<h3>Planned for February</h3>
<h4><a name="plan1-jan-18">Continue Development Projects</a></h4>
<p>In February, we’ll continue working on our January projects. Our plans include:</p>
<ul>
<li>Converting more compatibility data</li>
<li>Serving developer.mozilla.org from a CDN</li>
<li>Updating third-party libraries for compatibility with Django 1.11</li>
<li>Designing interactive examples for more complex scenarios</li>
<li>Preparing for a team meeting and “Hack on MDN” event in March</li>
</ul>
<p>See the
<a href="https://mozilla.github.io/meao/2018/01/08/kuma-report/#planned-for-january">December report</a>
for more information on these projects.</p>Wed, 07 Feb 2018 00:00:00 +0000K Lars Lohn: Lars and the Real Internet of Things - Part 1tag:blogger.com,1999:blog-12340845.post-8322108301003084812http://www.twobraids.com/2018/02/lars-and-real-internet-of-things-part-1.html
<i>This is the first in a series of blog postings about the Internet of Things (IoT). I'm going to cover some history, and then talk about and demonstrate <a href="https://iot.mozilla.org/">Mozilla's secure privacy protecting Things Gateway</a> and finally talk about writing the software for my own IoT devices to work with the Things Gateway. </i><br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-0yTmkJmXXmk/WnoLi9DNF_I/AAAAAAAApIQ/Cw6_8DAGoAATCkjdk9HY9EuUDivxHWL5ACLcBGAs/s1600/light_bulb.2.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="https://3.bp.blogspot.com/-0yTmkJmXXmk/WnoLi9DNF_I/AAAAAAAApIQ/Cw6_8DAGoAATCkjdk9HY9EuUDivxHWL5ACLcBGAs/s200/light_bulb.2.png" width="200" /></a></div><br />First, though, my history with home automation:<br /><br />When I was a teenager in the 1970s, I had an analog alarm clock with an electrical outlet on the back labeled "coffee". About ten minutes before the alarm would go off, it would turn on the power to the outlet. This was apparently to start a coffee maker that had been setup the night before. I, instead, used the outlet to turn on my record player so I could wake to music of my own selection. Ten years after the premier of the Jetsons automated utopia, this was the extent of home automation available to the average consumer.<br /><br />By the late 1970s and into the 1980s, the landscape changed in consumer home automation. A Scottish electronics company conceived of a remote control system that would communicate over power lines. By the mid 1980s, the <a href="https://en.wikipedia.org/wiki/X10_(industry_standard)">X10</a> system of controllers and devices was available at Radio Shack and many other stores.<br /><div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-lOqh7F-YAbk/WnntXaj7VMI/AAAAAAAApHs/EeSaB0b2vJYCQoaRdqPwo4jw6AfoNXevACLcBGAs/s1600/x10.appliance.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-lOqh7F-YAbk/WnntXaj7VMI/AAAAAAAApHs/EeSaB0b2vJYCQoaRdqPwo4jw6AfoNXevACLcBGAs/s320/x10.appliance.jpg" width="305" /></a></div><br />I was an early adopter of this technology, automating lamps, ceiling lights and porch lights. After the introduction of an RS-232 controller that allowed the early MS-DOS PCs to control lights, I was able to get porch lights to follow sunrise, sunset and daylight savings rules.<br /><br />X10 was unreliable. In communicating over power lines, it encoded its data into the momentary zero voltage between the peaks of alternating current: it maxed out at about 20 bits per second. Nearly anything could garble communication: the dish washer, the television, the neighbor's electric drill. Many of the components were poorly manufactured. Wall switches not only completely lacked style and ergonomics, but they would last only a year or so before requiring replacement. In 1990, a power surge during a thunderstorm wiped out almost all of my X10 devices. I was done with X10, it was too expensive and unreliable. <br /><br />For the next twenty years, I lived just fine without home automation, but the industry advanced. <a href="https://en.wikipedia.org/wiki/Insteon">Insteon</a>, <a href="https://en.wikipedia.org/wiki/Zwave">Z-Wave</a> and <a href="https://en.wikipedia.org/wiki/Zigbee">Zigbee</a> were all invented in the 2000s for home automation. Their high cost and my soured experience with X10, kept me away.<br /><br /><a href="https://4.bp.blogspot.com/-NMle830ksmo/WnntmW-gCYI/AAAAAAAApHw/mR5WN_y6RxMnkw8tNPrE3gcd_DYV_f6CgCLcBGAs/s1600/2018-02-06%2B09.54.23.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-NMle830ksmo/WnntmW-gCYI/AAAAAAAApHw/mR5WN_y6RxMnkw8tNPrE3gcd_DYV_f6CgCLcBGAs/s320/2018-02-06%2B09.54.23.jpg" width="240" /></a>In the last ten years, there has been a <span class="u-headword">renaissance in home automation in connection with the Internet: the Internet of Things. I looked at the new options, saw they were still expensive and they had new flaws: security and privacy. I bought a couple of the Belkin Wemo devices that I could control with my iPhone and found they were, like X10, unreliable. Sometimes they'd work and sometimes they wouldn't. Then in 2013, a security flaw was found that could result in someone else taking control or even invade the home network. The Wemo devices required a firmware security update and on hurting my back crawling behind the couch to do the update, I decided they were not worth the effort. The Wemo devices were added to my local landfill. </span><br /><span id="goog_539725708"></span><span id="goog_539725709"></span><br /><br />I watched from the sidelines as more and more companies jumped into the IoT field. A little research showed how ZWave and Zigbee devices could be more secure, but with two competing incompatible standards, how could I decide? I didn't want to buy the wrong thing and then suffer a orphaned system. I couldn't justify the expense.<br /><br />What really got me interested again were the <a href="https://en.wikipedia.org/wiki/Philips_Hue">Phillips Hue system</a> of color changeable lights. The cost coupled with Phillips on again, off again willingness to allow third party products to interact with their hub, forestalled my adoption.<br /><br />I held back until the <a href="https://en.wikipedia.org/wiki/SmartThings">Samsung SmartThings</a> device was introduced. Here was a smart home hub that could talk to both ZWave and Zigbee devices. I added one to my Amazon shopping cart along with a number of lamp controller switches. I didn't press the buy button because I was looking for the flaw. Of course, there was one, a big one: the Internet was required. Since it relied on mobile phones to control the Smart Home hub, if the Internet was down, the control of the devices stopped. Or so it seemed, the documentation was vague on the subject. I finally confirmed it by talking with an acquaintance that had the system. This system was not for me.<br /><br />I was again a IoT wallflower, longing to dance but unwilling to step onto the dance floor.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-LWpAdXg3-eI/Wnn1D4-O0QI/AAAAAAAApIA/XL1PLF4BnzYaoKdp2tbShPN9Xnla-DSgQCLcBGAs/s1600/og_hero_image.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="168" src="https://2.bp.blogspot.com/-LWpAdXg3-eI/Wnn1D4-O0QI/AAAAAAAApIA/XL1PLF4BnzYaoKdp2tbShPN9Xnla-DSgQCLcBGAs/s320/og_hero_image.png" width="320" /></a></div>In December of 2017, however, I saw a demonstration of a new experimental system from Mozilla called the <a href="https://iot.mozilla.org/">Things Gateway</a>. It offers a protocol agnostic control over IoT devices. It can control the Z-Wave and the Zigbee stuff at the same time. The software runs on a computer, even a Raspberry Pi. Because it offers a web server on the local home network, any Web browser on a phone, tablet or desktop machine at home can control it. Unlike most commercial IoT controllers, if the internet is out, I can still control things while I'm home. As a plus, Mozilla offers a secure method from the internet to the local Things Gateway web server. For many folks controlling things while away from home is important, for me, I could do without that feature. <br /><br />The final convincing argument? It's open source and completely customizable. I cannot resist any longer. <br /><br />My next blog posting will walk through the process of downloading and setting up a Mozilla Things Gateway. I'll show how I connected Z-Wave, Zigbee and Philips Hue lights into one smart home network. Subsequent postings will show how I can use the Python programming language to enable new devices to join the Internet of Things.<br /><br />I'm quite excited about this project.<br /><br /><a href="https://iot.mozilla.org/">Mozilla Things Gateway</a><br /><br /><a href="https://hacks.mozilla.org/2018/02/how-to-build-your-own-private-smart-home-with-a-raspberry-pi-and-mozillas-things-gateway/">Mozilla Hacks Blog about Things Gateway</a><br /><br /><h3><span class="me"><br /></span></h3>Tue, 06 Feb 2018 21:08:30 +0000noreply@blogger.com (K Lars Lohn)Hacks.Mozilla.Org: How to build your own private smart home with a Raspberry Pi and Mozilla’s Things Gatewayhttps://hacks.mozilla.org/?p=31817https://hacks.mozilla.org/2018/02/how-to-build-your-own-private-smart-home-with-a-raspberry-pi-and-mozillas-things-gateway/
<p>Last year we <a href="https://hacks.mozilla.org/2017/06/building-the-web-of-things/">announced</a> Project Things by Mozilla. Project Things is a framework of software and services that can bridge the communication gap between connected devices by giving “things” URLs on the web.</p>
<p>Today I’m excited to tell you about the latest version of the <a href="https://iot.mozilla.org/gateway/">Things Gateway</a> and how you can use it to directly monitor and control your home over the web, without a middleman. Instead of installing a different mobile app for every smart home device you buy, you can manage all your devices through a single secure web interface. This blog post will explain how to build your own Web of Things gateway with a Raspberry Pi and use it to connect existing off-the-shelf smart home products from various different brands using the power of the open web.</p>
<p>There are lots of exciting new features in the latest version of the gateway, including a rules engine for setting ‘<i>if this, then that’</i> style rules for how things interact, a floorplan view to lay out devices on a map of your home, experimental voice control and support for many new types of “things”. There’s also a brand new add-ons system for adding support for new protocols and devices, and a new way to safely authorise third party applications to access your gateway.</p>
<p><strong><img alt="" class="aligncenter wp-image-31878 size-full" height="480" src="https://hacks.mozilla.org/files/2018/02/things.png" width="800" /></strong></p>
<h3>Hardware</h3>
<p>The first thing to do is to get your hands on a Raspberry Pi® single board computer. The latest <a href="https://www.raspberrypi.org/products/raspberry-pi-3-model-b/">Raspberry Pi 3</a> has WiFi and Bluetooth support built in, as well as access to GPIO ports for direct hardware connections. This is not essential as you can use alternative developer boards, or even your laptop or desktop computer, but it currently provides the best experience.</p>
<p><img alt="" class="aligncenter size-medium wp-image-31826" height="166" src="https://hacks.mozilla.org/files/2018/01/raspberry_pi-250x166.png" width="250" /></p>
<p>If you want to use smart home devices using other protocols like Zigbee or Z-Wave, you will need to invest in USB dongles. For Zigbee we currently support the <a href="https://www.digi.com/products/xbee-rf-solutions/boxed-rf-modems-adapters/xstick">Digi XStick</a> (ZB mesh version). For Z-Wave you should be able to use any <a href="https://github.com/OpenZWave/open-zwave/wiki/Controller-Compatibility-List">OpenZWave compatible dongle</a>, but so far we have only tested the <a href="http://www.vesternet.com/z-wave-sigma-designs-usb-controller">Sigma Designs UZB Stick</a> and the <a href="http://aeotec.com/z-wave-usb-stick">Aeotec Z-Stick</a> (Gen5). Be sure to get the correct device for your region as Z-Wave operating frequencies can vary between countries.</p>
<p><img alt="" class="aligncenter size-medium wp-image-31827" height="157" src="https://hacks.mozilla.org/files/2018/01/usb_dongle-250x157.png" width="250" /></p>
<p>You’ll also need a microSD card to flash the software onto! We recommend at least 4GB.</p>
<p><img alt="" class="aligncenter size-medium wp-image-31828" height="157" src="https://hacks.mozilla.org/files/2018/01/sd_card-250x157.png" width="250" /></p>
<p>Then there’s the “things” themselves. The gateway already supports many different smart plugs, sensors and smart bulbs from lots of different brands using Zigbee, Z-Wave and WiFi. Take a look at the <a href="https://github.com/mozilla-iot/wiki/wiki/Supported-Hardware">wiki</a> for devices which have already been tested. If you would like to contribute, we are always looking for volunteers to help us test more devices. Let us know what other devices you’d like to see working and consider building your own adapter add-on to make it work! (see later).</p>
<p>If you’re not quite ready to splash out on all this hardware, but you want to try out the gateway software, there’s now a Virtual Things add-on you can install to add virtual things to your gateway.</p>
<h3>Software</h3>
<p>Next you’ll need to <a href="https://iot.mozilla.org/gateway">download</a> the Things Gateway 0.3 software image for the Raspberry Pi and flash it onto your SD card. There are <a href="https://www.raspberrypi.org/documentation/installation/installing-images/">various ways</a> of doing this but <a href="https://etcher.io/">Etcher</a> is a graphical application for Windows, Linux and MacOS which makes it easy and safe to do.</p>
<p><img alt="" class="aligncenter wp-image-31838 size-large" height="237" src="https://hacks.mozilla.org/files/2018/01/etcher-500x237.png" width="500" /></p>
<p>If you want to experiment with the gateway software on your laptop or desktop computer, you can follow the <a href="https://github.com/mozilla-iot/gateway/blob/master/README.md">instructions on GitHub</a> to download and build it yourself. We also have an experimental OpenWrt package and support for more platforms is coming soon. <a href="https://iot.mozilla.org/contribute/">Get in touch</a> if you’re targeting a different platform.</p>
<h3>First Time Setup</h3>
<p>Before booting up your gateway with the SD card inserted, ensure that any Zigbee or Z-Wave USB dongles are plugged in.</p>
<p>When you first boot the gateway, it acts as a WiFi hotspot broadcasting the network name (SSID) “Mozilla IoT Gateway”. You can connect to that WiFi hotspot with your laptop or smartphone which should automatically direct you to a setup page. Alternatively, you can connect the Raspberry Pi directly to your network using a network cable cable and type <b>gateway.local</b> into your browser to begin the setup process.</p>
<p>First, you’re given the option to connect to a WiFi network:</p>
<p> </p>
<p><img alt="" class="aligncenter wp-image-31879 size-full" height="480" src="https://hacks.mozilla.org/files/2018/02/wifi_list.png" width="800" /></p>
<p>If you choose to connect to a WiFi network you’ll be prompted for the WiFi password and then you’ll need to make sure you’re connected to that same network in order to continue setup.</p>
<p><img alt="" class="aligncenter wp-image-31880 size-full" height="480" src="https://hacks.mozilla.org/files/2018/02/wifi_connecting.png" width="800" /></p>
<p>Next, you’ll be asked to choose a unique subdomain for your gateway, which will automatically generate an SSL certificate for you using <a href="https://letsencrypt.org/">LetsEncrypt</a> and set up a secure tunnel to the Internet so you can access the gateway remotely. You’ll be asked for an email address so you can reclaim your subdomain in future if necessary. You can also choose to use your own domain name if you don’t want to use the tunneling service, but you’ll need to generate your own SSL certificate and configure DNS yourself.</p>
<p><img alt="" class="aligncenter wp-image-31881 size-full" height="480" src="https://hacks.mozilla.org/files/2018/02/choose_subdomain.png" width="800" /></p>
<p>You will then be securely redirected to your new subdomain and you’ll be prompted to create your user account on the gateway.</p>
<p><img alt="" class="aligncenter wp-image-31882 size-full" height="480" src="https://hacks.mozilla.org/files/2018/02/create_account.png" width="800" /></p>
<p>You’ll then automatically be logged into the gateway and will be ready to start adding things. Note that the gateway’s web interface is a Progressive Web App that you can <a href="https://hacks.mozilla.org/2017/10/progressive-web-apps-firefox-android/">add to homescreen</a> on your smartphone with Firefox.</p>
<p><img alt="" class="aligncenter wp-image-31883 size-full" height="480" src="https://hacks.mozilla.org/files/2018/02/things_empty.png" width="800" /></p>
<h3>Adding Things</h3>
<p>To add devices to your gateway, click on the “+” icon at the bottom right of the screen. This will put all the attached adapters into pairing mode. Follow the instructions for your individual device to pair it with the gateway (this often involves pressing a button on the device while the gateway is in pairing mode).</p>
<p>Devices that have been successfully paired with the gateway will appear in the add device screen and you can give them a name of your choice before saving them on the gateway.</p>
<p><img alt="" class="aligncenter wp-image-31884 size-full" height="480" src="https://hacks.mozilla.org/files/2018/02/add_things.png" width="800" /></p>
<p>The devices you’ve added will then appear on the Things screen.</p>
<p><img alt="" class="aligncenter wp-image-31885 size-full" height="480" src="https://hacks.mozilla.org/files/2018/02/smart_plugs.png" width="800" /></p>
<p>You can turn things on and off with a single tap, or click on the expand button to go to an expanded view all of all the thing’s properties. For example a smart plug has an on/off switch and reports its current power consumption, voltage, current and frequency.</p>
<p><img alt="" class="aligncenter wp-image-31886 size-full" height="543" src="https://hacks.mozilla.org/files/2018/02/zigbee_smart_plug.png" width="800" /></p>
<p>With a dimmable colour light, you can turn the light on and off, set its colour, and set its brightness level.</p>
<p><img alt="" class="aligncenter wp-image-31887 size-full" height="543" src="https://hacks.mozilla.org/files/2018/02/dimmable_color_light.png" width="800" /></p>
<h3>Rules Engine</h3>
<p>By clicking on the main menu you can access the rules engine.</p>
<p><img alt="" class="aligncenter wp-image-31889 size-full" height="480" src="https://hacks.mozilla.org/files/2018/02/main_menu-1.png" width="800" /></p>
<p>The rules engine allows you to set ‘<i>if this, then that’</i> style rules for how devices interact with each other. For example, “If Smart Plug A turns on, turn on Smart Plug B”.</p>
<p>To create a rule, first click the “+” button at the bottom right of the rules screen. Then drag and drop things onto the screen and select the properties of the things you wish to connect together.</p>
<p> </p>
<p><img alt="" class="aligncenter wp-image-31890 size-full" height="480" src="https://hacks.mozilla.org/files/2018/02/create_rule.png" width="800" /></p>
<p>You can give your rule a name and then click back to get back to the rules screen where you’ll see your new rule has been added.</p>
<p><img alt="" class="aligncenter wp-image-31891 size-full" height="480" src="https://hacks.mozilla.org/files/2018/02/rules.png" width="800" /></p>
<h3>Floorplan</h3>
<p>Clicking on the “floorplan” option from the main menu allows you to arrange devices on a floorplan of your home. Click the edit button at the bottom right of the screen to upload a floorplan image.</p>
<p><img alt="" class="aligncenter size-full wp-image-31848" height="480" src="https://hacks.mozilla.org/files/2018/01/floorplan_empty.png" width="800" /></p>
<p>You’ll need to create the floorplan image yourself. This can be done with an online tool or graphics editor, or you can just scan of a hand drawn map of your home! An SVG file with white lines and a transparent background works best.</p>
<p>You can arrange devices on the floor plan by dragging them around the screen.</p>
<p><img alt="" class="aligncenter size-full wp-image-31849" height="480" src="https://hacks.mozilla.org/files/2018/01/floorplan_edit.png" width="800" /></p>
<p>Just click “save” when you’re done and you’ll see all of your devices laid out. You can click on them to access their expanded view.</p>
<p><img alt="" class="aligncenter size-full wp-image-31850" height="480" src="https://hacks.mozilla.org/files/2018/01/floorplan.png" width="800" /></p>
<h3>Add-ons</h3>
<p>The gateway has an add-ons system so that you can extend its capabilities. It comes with the Zigbee and Z-Wave adapter add-ons installed by default, but you can add support for additional adapters through the add-ons system under “settings” in the main menu.</p>
<p><img alt="" class="aligncenter size-full wp-image-31851" height="480" src="https://hacks.mozilla.org/files/2018/01/add-ons.png" width="800" />Click the “+ Add” button on any add-on you want to install.</p>
<p>For example, there is a Virtual Things add-on which allows you to experiment with different types of web things without needing to buy any real hardware. Click the “+” button at the bottom right of the screen to see a list of available add-ons.</p>
<p><img alt="" class="aligncenter size-full wp-image-31852" height="480" src="https://hacks.mozilla.org/files/2018/01/add-addon.png" width="800" /></p>
<p>Click the “+ Add” button on any add-ons you want to install. When you navigate back to the add-ons screen you’ll see the list of add-ons that have been installed and you can enable or disable them.</p>
<p><img alt="" class="aligncenter size-full wp-image-31853" height="480" src="https://hacks.mozilla.org/files/2018/01/addon-added.png" width="800" /></p>
<p>In the next blog post, you’ll learn how to create, package, and share your own adapter add-ons in the programming language of your choice (e.g. JavaScript, Python or Rust).</p>
<h3>Voice UI</h3>
<p>The gateway also comes with experimental voice controls which are turned off by default. You can enable this feature through “experiments” in settings.</p>
<p><img alt="" class="aligncenter size-full wp-image-31854" height="480" src="https://hacks.mozilla.org/files/2018/01/experiments.png" width="800" /></p>
<p>Once the “Speech Commands” experiment is turned on you’ll notice a microphone icon appear at the top right of the things screen.</p>
<p><img alt="" class="aligncenter wp-image-31892 size-full" height="480" src="https://hacks.mozilla.org/files/2018/02/speech.png" width="800" /></p>
<p>If the smartphone or PC you’re using has a microphone you can tap the microphone and issue a voice command like “Turn kitchen on” to control devices connected to the gateway.</p>
<p>The voice control is still very experimental and doesn’t yet recognise a very wide range of vocabulary, so it’s best to try to stick to common words like kitchen, balcony, living room, etc. This is an area we’ll be working on improving in future, in collaboration with the <a href="https://voice.mozilla.org/">Voice</a> team at Mozilla.</p>
<h3>Updates</h3>
<p>Your gateway software should automatically keep itself up to date with over-the-air updates from Mozilla. You can see what version of the gateway software you’re running by clicking on “updates” in Settings.</p>
<p><img alt="" class="aligncenter size-full wp-image-31856" height="480" src="https://hacks.mozilla.org/files/2018/01/updates.png" width="800" /></p>
<h3>What’s Coming Next?</h3>
<p>In the next release, the Mozilla IoT team plans to create new gateway adapters to connect more existing smart home devices to the Web of Things. We are also starting work on a collection of software libraries in different programming languages, to help hackers and makers build their own native web things which directly expose the <a href="https://iot.mozilla.org/wot/">Web Thing API</a>, using existing platforms like Arduino and Android Things. You will then be able to add these things to the gateway by their URL.</p>
<p>We will continue to contribute to standardisation of a Web Thing Description format and API via the <a href="https://www.w3.org/WoT/">W3C Web of Things Interest Group</a>. By giving connected devices URLs on the web and using a standard data model and API, we can help create more interoperability on the Internet of Things.</p>
<p>The next blog post will explain how to build, package and share your own adapter add-on using the programming language of your choice, to add new capabilities to the Things Gateway.</p>
<h3>How to Contribute</h3>
<p>We need your help! The easiest way to contribute is to <a href="https://iot.mozilla.org/gateway/">download</a> the Things Gateway software image (0.3 at the time of writing) and test it out for yourself with a Raspberry Pi, to help us find bugs and suggest new features. You can view our <a href="https://github.com/mozilla-iot/gateway">source code</a> and <a href="https://github.com/mozilla-iot/gateway">file issues</a> on GitHub. You can also help us fix issues with pull requests and contribute your own adapters for the gateway.</p>
<p>If you want to ask questions, you can find us in #iot on <a href="https://wiki.mozilla.org/IRC">irc.mozilla.org</a> or the “Mozilla IoT” topic in <a href="https://discourse.mozilla.org/c/iot">Discourse</a>. See <a href="https://iot.mozilla.org">iot.mozilla.org</a> for more information and follow <a href="https://twitter.com/MozillaIoT">@MozillaIoT</a> on Twitter if you want to be kept up to date with developments.</p>
<p>Happy hacking!</p>
<p> </p>Tue, 06 Feb 2018 17:07:40 +0000Ben FrancisThe Mozilla Blog: Announcing “Project Things” – An open framework for connecting your devices to the web.https://blog.mozilla.org/?p=11223https://blog.mozilla.org/blog/2018/02/06/announcing-project-things-open-framework-connecting-devices-web/
<p>Last year, we <a href="https://hacks.mozilla.org/2017/06/building-the-web-of-things/" rel="noopener" target="_blank">said</a> that Mozilla is working to create a framework of software and services that can bridge the communication gap between connected devices. Today, we are pleased to announce that anyone can now build their own Things Gateway to control their connected device directly from the web.</p>
<p>We kicked off “Project Things”, with the goal of building a decentralized ‘Internet of Things’ that is focused on security, privacy, and interoperability. Since our announcement last year, we have continued to engage in open and collaborative development with a community of makers, testers, contributors, and end-users, to build the foundation for this future.</p>
<p>Today’s launch makes it easy for anyone with a Raspberry Pi to build their own Things Gateway. In addition to web-based commands and controls, a new experimental feature shows off the power and ease of using voice-based commands. We believe this is the most natural way for users to interact with their smart home. Getting started is easy, and we recommend checking out <a href="https://hacks.mozilla.org/2018/02/how-to-build-your-own-private-smart-home-with-a-raspberry-pi-and-mozillas-things-gateway/" rel="noopener" target="_blank">this tutorial</a> to get connected.</p>
<h3>The Future of Connected Devices</h3>
<p>Internet of Things (IoT) devices have become more popular over the last few years, but there is no single standard for how these devices should talk to each other. Each vendor typically creates a custom application that only works with their own brand. If the future of connected IoT devices continues to involve proprietary solutions, then costs will stay high, while the market remains fragmented and slow to grow. Consumers should not be locked into a specific product, brand, or platform. This will only lead to paying premium prices for something as simple as a “smart light bulb”.</p>
<p>We believe the future of connected devices should be more like the open web. The future should be decentralized, and should put the power and control into the hands of the people who use those devices. This is why we are committed to defining open standards and frameworks.</p>
<h3>A Private “Internet of Things”</h3>
<p>Anyone can build a Things Gateway using popular devices such as the Raspberry Pi. Once it is set up, it will guide you through the process of connecting to your network and adding your devices. The setup process will provide you with a secure URL that can be used to access and control your connected devices from anywhere.</p>
<h3>Powerful New Features</h3>
<p>Our latest release of the Things Gateway has several new features available. These features include:</p>
<ul>
<li>The ability to use the microphone on your computer to issue voice commands</li>
<li>A rules engine for setting ‘If this, then that’ logic for how devices interact with each other</li>
<li>A floor-plan view to lay out devices on a map of your home</li>
<li>Additional device type support, such as smart plugs, dimmable and colored lights, multi-level switches and sensors, and “virtual” versions of them, in case you don’t have a real device</li>
<li>An all-new add-on system for supporting new protocols and devices</li>
<li>A new system for safely authorizing third-party applications (using OAuth)</li>
</ul>
<h3>Built for <s>hackers</s> everyone</h3>
<p>If you have been following our progress with Project Things, you’ll know that up to now, it was only really accessible to those with a good amount of technical knowledge. With today’s release, we have made it easy for anyone to get started on building their own Things Gateway to control their devices. We take care of the complicated stuff so that you can focus on the fun stuff such as automation, ‘if this, then that’ rules, adding a greater variety of devices, and more.</p>
<h3>Getting Started</h3>
<p>We have provided a full walkthrough of how to get started on building your own private smart home using a Raspberry Pi. You can view the complete walkthrough <a href="https://hacks.mozilla.org/2018/02/how-to-build-your-own-private-smart-home-with-a-raspberry-pi-and-mozillas-things-gateway/" rel="noopener" target="_blank">here</a>.</p>
<p>If you have questions, or you would like to get involved with this project you can join the #iot channel on <a href="http://irc.mozilla.org" rel="noopener" target="_blank">irc.mozilla.org</a> and participate in the development on <a href="https://github.com/mozilla-iot" rel="noopener" target="_blank">GitHub</a>. You can also follow <a href="http://www.twitter.com/mozillaiot" rel="noopener" target="_blank">@MozillaIoT</a> on twitter for the latest news.</p>
<p>For more information, please visit <a href="https://iot.mozilla.org" rel="noopener" target="_blank">iot.mozilla.org</a>.</p>
<p>The post <a href="https://blog.mozilla.org/blog/2018/02/06/announcing-project-things-open-framework-connecting-devices-web/" rel="nofollow">Announcing “Project Things” – An open framework for connecting your devices to the web.</a> appeared first on <a href="https://blog.mozilla.org" rel="nofollow">The Mozilla Blog</a>.</p>Tue, 06 Feb 2018 17:06:47 +0000MozillaDaniel Stenberg: Nordic Free Software Award rebornhttps://daniel.haxx.se/blog/?p=10827https://daniel.haxx.se/blog/2018/02/06/nordic-free-software-award-reborn/
<p><a href="https://survey.fsfe.org/index.php/167339"><img alt="" class="alignright size-medium wp-image-2210" height="300" src="https://daniel.haxx.se/blog/wp-content/uploads/2010/11/NFSA-award-239x300.jpg" width="239" /></a>Remember the glorious year 2009 when <a href="https://daniel.haxx.se/blog/2009/11/14/i-won-it-you-guys-are-the-best/">I won the Nordic Free Software Award</a>?</p>
<p>This award tradition that was started in 2007 was put on a hiatus after <a href="https://daniel.haxx.se/blog/2010/11/07/bjarni-got-the-award-2010/">2010</a> (I believe) and there has not been any awards handed out since, and we have not properly shown our appreciation for the free software heroes of the Nordic region ever since.</p>
<p>The award has now been reignited by Jonas Öberg of <a href="https://fsfe.org/">FSFE</a> and you’re all encourage to <a href="https://survey.fsfe.org/index.php/167339">nominate your favorite Nordic free software people</a>!</p>
<p>Go ahead and do it right away! You only have to the end of February so you better do it now before you forget about it.</p>
<p>I’m honored to serve on the award jury together with previous award winners.</p>
<p>This year’s Nordic Free Software Award winner will be announced and handed their prize at the <a href="http://foss-north.se/2018/">FOSS-North conference</a> on April 23, 2018.</p>
<p>(Okay, yes, the “photo” is a montage and not actually showing a real trophy.)</p>Tue, 06 Feb 2018 13:32:21 +0000Daniel StenbergDon Marti: Fun with numbershttps://blog.zgp.org/fun-with-numbers/https://blog.zgp.org/fun-with-numbers/
<p><em>(I work for Mozilla. None of this is secret. None of this is official Mozilla policy. Not speaking for Mozilla here.)</em></p>
<p>Guess what? According to Emil Protalinski
at VentureBeat, <a href="https://venturebeat.com/2018/01/26/probeat-google-chrome-and-mozilla-firefox-are-bringing-back-the-browser-wars/">the browser wars are back
on</a>.</p>
<blockquote>
<p>Google is doubling down on the user experience by focusing on ads and performance, an opportunity I’ve argued its competitors have completely missed. </p>
</blockquote>
<p>Good point. Jonathan Mendez
has some <a href="https://jonathanmendezblog.com/2017/12/04/the-decade-of-display-that-wasnt/">good background on
that</a>.</p>
<blockquote>
<p>The IAB road blocked the W3C Do Not Track initiative in 2012 that was led by a cross functional group that most importantly included the browser makers. In hindsight this was the only real chance for the industry to solve consumer needs around data privacy and advertising technology. The IAB wanted self-regulation. In the end, DNT died as the IAB hoped. </p>
</blockquote>
<p>As third-party tracking made the ad experience
crappier and crappier, browser makers tried to play
nice. Browser makers tried to work in the open and
build consensus.</p>
<p>That didn't work, which shouldn't be a surprise.
Imagine if email providers had decided to
build consensus with spammers about spam
filtering rules. The spammers would have
been all like, <a href="https://www.iab.com/news/mozilla-kangaroo-cookie-court/">"It replaces the principle of
consumer choice with an arrogant 'Hotmail knows best'
system."</a>
Any sensible email provider would ignore the spammers
but listen to deliverability concerns from senders of
legit opt-in newsletters. Spammers depend on sneaking
around the user's intent to get their stuff through,
so email providers that want to get and keep users
should stay on the user's side. Fortunately for legit
mail senders and recipients, that's what happened.</p>
<p>On the web, though, not so much.</p>
<p>But now Apple Safari <a href="https://blog.zgp.org/apple-s-kangaroo-cookie-robot/">has Intelligent Tracking
Prevention</a>.
Industry consensus achieved? No way.
Safari's developers put users first and, like
the man said, <a href="https://www.theguardian.com/technology/2018/jan/09/apple-tracking-block-costs-advertising-companies-millions-dollars-criteo-web-browser-safari">if you're not first you're
last</a>.</p>
<p>And now Google is doing their own thing.
Some positive parts about it, but by
focusing on filtering annoying types of
ad units they're closer to the Adblock Plus
"Acceptable Ads" racket than to a real solution.
So it's better to let <a href="https://adblockplus.org/blog/what-will-google-chrome-s-new-ad-filter-actually-block-we-investigate">Ben Williams at Adblock
Plus</a>
explain that one. I still don't get how it is that
so many otherwise capable people come up with "let's
filter superficial annoyances and not fundamental
issues" and "let's shake down legit publishers
for cash" as solutions to the web advertising
problem, though. Especially when <a href="http://www.businessinsider.com/ad-fraud-estimates-doubled-2017-3">$16 billion in
adfraud</a>
is just sitting there. It's almost as if the
Lumascape doesn't care about fraud because it's
<a href="http://blog.aloodo.org/posts/thank-you-for-supporting-fraud/">priced in so it comes out of the publisher's share
anyway</a>.</p>
<p>So with all the money going to fraud
and the intermediaries that facilitate
it, <a href="https://digiday.com/media/local-digital-news-publishers-ignoring-display-revenue/">local digital news publishers are
looking for money in other places and writing off
ads.</a>
That's good news for the surviving web ad optimists
(like me) because any time Management stops caring
about something you get a big opportunity to do
something transformative.</p>
<h3>Small victories</h3>
<p>The web advertising problem looks big, but I want to think positive about it.</p>
<ul>
<li><p>billions of web users</p>
</li>
<li><p>visiting hundreds of web sites</p>
</li>
<li><p>with tens of third-party trackers per site.</p>
</li>
</ul>
<p>That's trillions of opportunities for tiny victories
against adfraud.</p>
<p>Right now most browsers and most fraudbots
are hard to tell apart. Both maintain
a single "cookie jar" across trusted and
untrusted sites, and both are subject to
<a href="https://w3c.github.io/fingerprinting-guidance/">fingerprinting</a>.</p>
<p>For fraudbots, cross-site trackability is a feature. A
fraudbot can only produce valuable ad impressions
on a fraud site if it is somehow trackable from a
legit site.</p>
<p>For browsers, cross-site trackability is a bug, for two reasons.</p>
<ul>
<li><p>Leaking activity from one context to another violates widely held user norms.</p>
</li>
<li><p>Because users enjoy ad-supported content, it is in the interest of users
to reduce the fraction of ad budgets that go to fraud and intermediaries.</p>
</li>
</ul>
<p>Browsers don't have the solve the whole web
advertising problem to make a meaningful difference.
As soon as a trustworthy site's real users look
diffferent enough from fraudbots, because fraudbots
make themselves more trackable than users running
tracking-protected browsers do, then low-reputation
and fraud sites claiming to offer the same audience
will have a harder and harder time trying to sell
impressions to agencies that can see it's not the
same people.</p>
<p>Of course, the browser market share numbers will
still over-represent any undetected fraudbots and
under-represent the "conscious chooser" users who
choose to turn on extra tracking protection options.
But that's an opportunity for creative ad agencies
that can buy underpriced post-creepy ad impressions
and stay away from overvalued or worthless bot
impressions. I expect that data on who has legit
users—made more accurate by including tracking
protection measurements—will be proprietary
to certain agencies and brands that are going after
customer segments with high tracking protection
adoption, at least for a while.</p>
<h3>Bonus links</h3>
<p><a href="https://twitter.com/arstechnica/status/956974282881593344">Now even YouTube serves ads with CPU-draining cryptocurrency miners http://arstechnica.com/information-technology/2018/01/now-even-youtube-serves-ads-with-cpu-draining-cryptocurrency-miners/ … by @dangoodin001</a></p>
<p><a href="https://www.georgesoros.com/2018/01/25/remarks-delivered-at-the-world-economic-forum/">Remarks delivered at the World Economic Forum</a></p>
<p><a href="https://blog.mozilla.org/data/2018/01/26/improving-privacy-without-breaking-the-web/">Improving privacy without breaking the web</a></p>
<p><a href="https://www.blog.google/topics/safety-security/greater-control-new-features-your-ads-settings/">Greater control with new features in your Ads Settings</a></p>
<p><a href="https://pagefair.com/blog/2018/pagefair-letter-to-article-29-working-party/">PageFair’s long letter to the Article 29 Working Party</a></p>
<p><a href="https://www.theguardian.com/media/2018/jan/23/never-get-high-on-your-own-supply-why-social-media-bosses-dont-use-social-media">‘Never get high on your own supply’ – why social media bosses don’t use social media</a></p>
<p><a href="https://twitter.com/groovecoder/status/955990674310074368">Can you detect WebDriver sessions from inside a web page? https://hoosteeno.com/2018/01/23/can-you-detect-webdriver-sessions-from-inside-a-web-page/ … via @wordpressdotcom</a></p>
<p><a href="https://hacks.mozilla.org/2018/01/making-webassembly-even-faster-firefoxs-new-streaming-and-tiering-compiler/">Making WebAssembly even faster: Firefox’s new streaming and tiering compiler</a></p>
<p><a href="http://www.niemanlab.org/2018/01/newsonomics-inside-l-a-s-journalistic-collapse/">Newsonomics: Inside L.A.’s journalistic collapse</a></p>
<p><a href="https://blog.appnexus.com/2018/state-ad-fraud/">The State of Ad Fraud</a></p>
<p><a href="https://www.theverge.com/2018/1/22/16920512/facebook-democracy-effects-social-media">The more Facebook examines itself, the more fault it finds</a></p>
<p><a href="https://medium.californiasun.co/in-n-out-store-managers-earn-160000-wages-b08fe6f1706f">In-N-Out managers earn triple the industry average</a></p>
<p><a href="https://medium.com/mydata/five-loopholes-in-the-gdpr-367443c4248b">Five loopholes in the GDPR</a></p>
<p><a href="https://product.voxmedia.com/2018/1/22/16902862/why-ads-redirect-to-giftcards-and-what-were-doing-to-secure-them">Why ads keep redirecting you to scammy sites and what we’re doing about it</a></p>
<p><a href="https://digiday.com/media/local-digital-news-publishers-ignoring-display-revenue/">https://digiday.com/media/local-digital-news-publishers-ignoring-display-revenue/</a></p>
<p><a href="http://freedom-to-tinker.com/2018/01/12/website-operators-are-in-the-dark-about-privacy-violations-by-third-party-scripts/">Website operators are in the dark about privacy violations by third-party scripts</a></p>
<p><a href="http://cbc.ca/radio/asithappens/as-it-happens-thursday-edition-1.4493061/mark-zuckerberg-s-former-mentor-says-parasitic-facebook-threatens-our-health-and-democracy-1.4493932">Mark Zuckerberg's former mentor says 'parasitic' Facebook threatens our health and democracy</a></p>
<p><a href="https://www.theatlantic.com/business/archive/2018/01/craft-beer-industry/550850/">Craft Beer Is the Strangest, Happiest Economic Story in America</a></p>
<p><a href="https://www.buzzfeed.com/tomphillips/twitterstorm-2018">The 29 Stages Of A Twitterstorm In 2018</a></p>
<p><a href="https://www.buzzfeed.com/meghara/facebook-cambodia-democracy">How Facebook Helped Ruin Cambodia's Democracy</a></p>
<p><a href="https://www.bloomberg.com/news/features/2017-12-21/inside-the-facebook-team-helping-regimes-that-reach-out-and-crack-down">How Facebook’s Political Unit Enables the Dark Art of Digital Propaganda</a></p>
<p><a href="https://www.janbambas.cz/firefox-57-delays-requests-tracking-domains/">Firefox 57 delays requests to tracking domains</a></p>
<p><a href="https://econsultancy.com/blog/69531-direct-ad-buys-are-back-in-fashion-as-programmatic-declines/">Direct ad buys are back in fashion as programmatic declines</a></p>
<p><a href="https://digiday.com/media/data-arbitrage-big-problem-media-arbitrage-confessions-media-exec/">‘Data arbitrage is as big a problem as media arbitrage’: Confessions of a media exec</a></p>
<p><a href="https://digiday.com/media/publishers-dont-name-shame-vendors-ad-fraud/">Why publishers don’t name and shame vendors over ad fraud</a></p>
<p><a href="https://digiday.com/media/news-uk-tests-finds-high-levels-domain-spoofing-tune-1m-month-lost-revenue/">News UK finds high levels of domain spoofing to the tune of $1 million a month in lost revenue • Digiday</a></p>
<p><a href="https://markpilip.com/2018/01/11/the-finish-line-in-the-race-to-the-bottom/">The Finish Line in the Race to the Bottom</a></p>
<p><a href="https://economist.com/news/business/21735029-stockmarket-investors-are-wrong-expect-enormous-surge-advertising-revenues-something">Something doesn’t ad up about America’s advertising market</a></p>
<p><a href="https://www.slideshare.net/augustinefou/marketers-take-control-run-experiments">Fraud filters don't work</a></p>
<p><a href="https://digiday.com/marketing/ad-retargeters-trying-work-around-gdpr-apple">Ad retargeters scramble to get consumer consent</a></p>Tue, 06 Feb 2018 08:00:00 +0000This Week In Rust: This Week in Rust 220tag:this-week-in-rust.org,2018-02-06:blog/2018/02/06/this-week-in-rust-220/https://this-week-in-rust.org/blog/2018/02/06/this-week-in-rust-220/
<p>Hello and welcome to another issue of <em>This Week in Rust</em>!
<a href="http://rust-lang.org">Rust</a> is a systems language pursuing the trifecta: safety, concurrency, and speed.
This is a weekly summary of its progress and community.
Want something mentioned? Tweet us at <a href="https://twitter.com/ThisWeekInRust">@ThisWeekInRust</a> or <a href="https://github.com/cmr/this-week-in-rust">send us a pull request</a>.
Want to get involved? <a href="https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md">We love contributions</a>.</p>
<p><em>This Week in Rust</em> is openly developed <a href="https://github.com/cmr/this-week-in-rust">on GitHub</a>.
If you find any errors in this week's issue, <a href="https://github.com/cmr/this-week-in-rust/pulls">please submit a PR</a>.</p>
<h3>Updates from Rust Community</h3>
<h4>News &amp; Blog Posts</h4>
<ul>
<li><a href="https://blog.rust-lang.org/2018/01/31/The-2018-Rust-Event-Lineup.html">The 2018 Rust event lineup</a>.</li>
<li><a href="https://aturon.github.io/2018/02/06/portability-vision/">A vision for portability in Rust</a>.</li>
<li><a href="https://boats.gitlab.io/blog/post/2018-01-30-async-ii-narrowing-the-scope/">Async/await II: Narrowing the scope of the problem</a>.</li>
<li><a href="https://boats.gitlab.io/blog/post/2018-01-30-async-iii-moving-forward/">Async/await III: Moving forward with something shippable</a>.</li>
<li><a href="http://smallcultfollowing.com/babysteps/blog/2018/02/01/in-rust-ordinary-vectors-are-values/">In Rust, ordinary vectors are values</a>.</li>
<li><a href="https://matklad.github.io/2018/01/03/make-your-own-make.html">Make your own make (build system)</a>.</li>
<li><a href="https://tinkering.xyz/posts/introduction-to-proc-macros/">Introduction to procedural macros</a>.</li>
<li><a href="https://www.ralfj.de/blog/2018/01/31/sharing-for-a-lifetime.html">Sharing for a Lifetime</a>. Some thoughts on how interior mutability fundamentally affects how we have to think about shared references, and how that relates to the private invariants maintained by a type.</li>
<li><a href="https://people.gnome.org/~federico/blog/writing-a-command-line-program-in-rust.html">Writing a command-line program in Rust</a>.</li>
<li><a href="https://jvns.ca/blog/2018/02/05/rust-bcc/">Writing eBPF tracing tools in Rust</a>.</li>
<li><a href="https://unhandledexpression.com/2018/02/02/poc-compiling-to-ebpf-from-rust/">Compiling to eBPF from Rust</a>.</li>
<li><a href="http://pramode.in/2018/01/31/ti-launchpad-with-rust-new-io/">Experimenting with the new I/O framework for embedded systems</a>.</li>
<li><a href="https://www.ncameron.org/blog/these-weeks-in-dev-tools-issue-3/">These weeks in dev-tools 3</a>.</li>
<li><a href="https://guillaumegomez.github.io/this-week-in-rust-docs/blog/this-week-in-rust-docs-91">This week in Rust docs 91</a>.</li>
<li>[podcast] <a href="http://www.newrustacean.com/show_notes/e022/">New Rustacean: e022 – <code>Send</code> and <code>Sync</code>: The “marker” traits Rust uses for safe concurrency</a></li>
<li>[podcast] <a href="https://rusty-spike.blubrry.net/2018/02/01/episode-17-jan-31-2018/">Rusty Spike Podcast - episode 17</a>. Awards, 2018 roadmap RFC, 2018 conferences, and KubOS.</li>
</ul>
<h3>Crate of the Week</h3>
<p>This week's crate is <a href="https://www.datafusion.rs">datafusion</a>, a query planner/execution framework for Big Data processing. Thanks to <a href="https://users.rust-lang.org/u/andygrove">andygrove</a> for the suggestion!</p>
<p><a href="https://users.rust-lang.org/t/crate-of-the-week/2704">Submit your suggestions and votes for next week</a>!</p>
<h3>Call for Participation</h3>
<p>Always wanted to contribute to open-source projects but didn't know where to start?
Every week we highlight some tasks from the Rust community for you to pick and get started!</p>
<p>Some of these tasks may also have mentors available, visit the task page for more information.</p>
<ul>
<li><a href="https://www.rustaceans.org/findwork/starters">Get started with these beginner-friendly issues</a>.</li>
<li><a href="https://users.rust-lang.org/t/rayon-1-0-on-feb-14/14950">Help Rayon prepare for 1.0</a>.</li>
<li><a href="https://github.com/Keats/gutenberg/issues/205">gutenberg: Make content::Section hold references</a>. Gutenberg is an opinionated static site generator with everything built-in.</li>
</ul>
<p>If you are a Rust project owner and are looking for contributors, please submit tasks <a href="https://users.rust-lang.org/t/twir-call-for-participation/4821">here</a>.</p>
<h3>Updates from Rust Core</h3>
<p>115 pull requests were <a href="https://github.com/search?q=is%3Apr+org%3Arust-lang+is%3Amerged+merged%3A2017-01-29..2018-02-05">merged in the last week</a></p>
<ul>
<li><a href="https://github.com/rust-lang/rust/pull/45294">syntax: lower priority of <code>+</code> in <code>impl Trait</code>/<code>dyn Trait</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47914">improve char escaping in lexer messages</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47947">stabilize <code>feature(match_beginning_vert)</code></a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/4990">add a <code>-Z no-index-update</code> for crater and benchmarking</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47895">fix ICE when reading non-UTF-8 input from stdin</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47912">use a range to identify SIGSEGV in stack guards</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47920">fix overflow when performing drop check calculations in NLL</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47873">fix ref-to-ptr coercions not working with NLL in certain cases</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47898">fix ICE when assigning references to a static mut with NLL</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47766">make region inference use a dirty list</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47540">add approximate suggestions for rustfix</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47780">add line numbers and columns to error messages spanning multiple files</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47896">don't lint unnecessary parens in function or method arguments inside of nested macros</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47677">avoid underflow in render_source_line</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47942">minimize weird spans involving macro context</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47791">tweak presentation on lifetime trait mismatch</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47829">suggest removing value from <code>break</code> when invalid</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47844">fix regression: account for trait methods in arg count mismatch error</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47865">cleanup the shim code</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47760">implement <code>Send</code> for <code>process::Command</code> on Unix</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47552">specialize <code>StepBy::nth</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/46666">move <code>Duration</code> to libcore</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47836">rustbuild: per-stage <code>RUSTFLAGS</code></a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/4984">cargo: allow configuration of LTO in <code>[profile]</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47862">rustdoc: fix const evaluation ICE</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/47855">rustdoc: fix link title rendering with hoedown</a></li>
</ul>
<h4>New Contributors</h4>
<ul>
<li>Araam Borhanian</li>
<li>dpc</li>
<li>Jay Strict</li>
<li>Jonathan Goodman</li>
<li>Matthias Krüger</li>
<li>oberien</li>
<li>Onur Aslan</li>
<li>penpalperson</li>
<li>Per Lundberg</li>
</ul>
<h4>Approved RFCs</h4>
<p>Changes to Rust follow the Rust <a href="https://github.com/rust-lang/rfcs#rust-rfcs">RFC (request for comments)
process</a>. These
are the RFCs that were approved for implementation this week:</p>
<ul>
<li><a href="https://github.com/rust-lang/rfcs/pull/2136">RFC 2136: Cargo build system integration</a>.</li>
</ul>
<h4>Final Comment Period</h4>
<p>Every week <a href="https://www.rust-lang.org/team.html">the team</a> announces the
'final comment period' for RFCs and key PRs which are reaching a
decision. Express your opinions now. <a href="https://github.com/rust-lang/rfcs/labels/final-comment-period">This week's FCPs</a> are:</p>
<ul>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/1909">Unsized rvalues</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2056">Allow trivial constraints to appear in where clauses</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2116">Fallible collection allocation 1.0</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2145">Type privacy and private-in-public lints</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2166">impl-only-use</a>. The <code>use …::{… as …}</code> syntax can now accept <code>_</code> as alias to a trait to only import the implementations of such a trait.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2175">or-patterns in if / while let expressions</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2195">Formally define repr(u32, i8, etc...) and repr(C) on enums with payloads</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2250">Finalize syntax of <code>impl Trait</code> and <code>dyn Trait</code> with multiple bounds</a>.</li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rfcs/pull/2298"><code>?</code> repetition in macro rules</a>.</li>
<li>[disposition: postpone] <a href="https://github.com/rust-lang/rfcs/pull/1546">Allow fields in traits that map to lvalues in impl'ing type</a>.</li>
<li>[disposition: postpone] <a href="https://github.com/rust-lang/rfcs/pull/1872">Fix the handling of uninhabited types in pattern matching</a>.</li>
<li>[disposition: postpone] <a href="https://github.com/rust-lang/rfcs/pull/1897">Unions 1.2</a>.</li>
<li>[disposition: postpone] <a href="https://github.com/rust-lang/rfcs/pull/2061">Allow destructuring of structs that implement Drop</a>.</li>
<li>[disposition: postpone] <a href="https://github.com/rust-lang/rfcs/pull/2148">Adding unsafe modules and unsafe blocks outside functions</a>.</li>
<li>[disposition: close] <a href="https://github.com/rust-lang/rfcs/pull/2221">Guard Clause Flow Typing</a>.</li>
<li>[disposition: close] <a href="https://github.com/rust-lang/rfcs/pull/2268">Legal double reference</a>.</li>
<li>[disposition: close] <a href="https://github.com/rust-lang/rfcs/pull/2144">Add match/in statements</a>.</li>
</ul>
<h4>New RFCs</h4>
<ul>
<li><a href="https://github.com/rust-lang/rfcs/pull/2318">Custom test frameworks</a>.</li>
<li><a href="https://github.com/rust-lang/rfcs/pull/2321">Default type parameter fallback revisited</a>.</li>
<li><a href="https://github.com/rust-lang/rfcs/pull/2320">Add macro expansion API to proc macros</a>.</li>
</ul>
<h3>Upcoming Events</h3>
<ul>
<li><a href="https://www.meetup.com/Finland-Rust-Meetup/events/246866694/">Feb 8. Helsinki - Finland Rust-lang Group</a>.</li>
<li><a href="https://www.meetup.com/columbus-rs/events/czcwhlyxdblb/">Feb 8. Columbus Rust Society - Monthly Meeting</a>.</li>
<li><a href="https://www.meetup.com/San-Diego-Rust/events/246906809/">Feb 8. San Diego Rust February Meetup</a>.</li>
<li><a href="https://internals.rust-lang.org/t/release-cycle-triage-proposal/3544">Feb 8. Rust release triage</a>.</li>
<li><a href="https://www.meetup.com/Rust-Rhein-Main/events/246744631">Feb 9. Rust Table of Regulars Darmstadt / Germany</a></li>
<li><a href="https://www.rustcon2k18.in/">Feb 10. Mangalore, India - RUSTCON2k18</a>.</li>
<li><a href="https://www.meetup.com/Rust-Dev-in-Mountain-View/events/glnfcpyxdbpb/">Feb 11. Rust Dev in Mountain View - Open Table / Icebreaker: what projects are you working on</a>.</li>
<li><a href="https://www.meetup.com/Rust-London-User-Group/events/246860921/">Feb 12. Rust London User Group - LDN Talks: February 2018</a>.</li>
<li><a href="https://www.meetup.com/Rust-Amsterdam/events/247120013/">Feb 12. Rust Amsterdam - Perl FFI &amp;&amp; Long-term reliability in Rust projects</a>.</li>
<li><a href="https://www.meetup.com/Seattle-Rust-Meetup/events/hztzcpyxdbqb/">Feb 12. Seattle Rust Meetup - Monthly meetup</a>.</li>
<li><a href="https://www.meetup.com/it-IT/Rust-Roma/events/247507331/">Feb 13. Rust Roma - Rust learning and hacking evening #6</a>.</li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-content">Feb 13. Rust Community Content Subteam Meeting at #rust-content on irc.mozilla.org</a></li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-community">Feb 14. Rust Community Team Meeting at #rust-community on irc.mozilla.org</a>.</li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-docs">Feb 14. Rust Documentation Team Meeting at #rust-docs on irc.mozilla.org</a>.</li>
<li><a href="https://www.meetup.com/Cambridge-Rust-Meetup/events/mgtcwnyxdbtb/">Feb 15. Cambridge Rust Meetup</a>.</li>
<li><a href="https://www.meetup.com/Rust-Dev-in-Mountain-View/events/glnfcpyxdbxb/">Feb 18. Rust Dev in Mountain View - Open Table / Icebreaker: what projects are you working on</a>.</li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-community">Feb 21. Rust Community Team Meeting at #rust-community on irc.mozilla.org</a>.</li>
<li><a href="https://chat.mibbit.com/?server=irc.mozilla.org&amp;channel=%23rust-docs">Feb 21. Rust Documentation Team Meeting at #rust-docs on irc.mozilla.org</a>.</li>
<li><a href="https://internals.rust-lang.org/t/release-cycle-triage-proposal/3544">Feb 22. Rust release triage</a>.</li>
<li><a href="https://www.meetup.com/Rust-London-User-Group/events/246860921/">Feb 22. Rust London User Group - LDN Talks: February 2018</a>.</li>
</ul>
<p>If you are running a Rust event please add it to the <a href="https://www.google.com/calendar/embed?src=apd9vmbc22egenmtu5l6c5jbfc%40group.calendar.google.com">calendar</a> to get
it mentioned here. Email the <a href="mailto:community-team@rust-lang.org">Rust Community Team</a> for access.</p>
<h3>Rust Jobs</h3>
<ul>
<li><a href="https://www.reddit.com/r/rust/comments/7utj4t/reddit_is_hiring_a_senior_rust_engineer/">Senior Rust Engineer at Reddit</a>.</li>
<li><a href="https://maidsafe.net/careers.html#rust_engineer">Rust Engineer at MaidSafe</a>.</li>
</ul>
<p><em>Tweet us at <a href="https://twitter.com/ThisWeekInRust">@ThisWeekInRust</a> to get your job offers listed here!</em></p>
<h3>Quote of the Week</h3>
<blockquote>
<blockquote>
<p>Rust has a very high friction coefficient.</p>
</blockquote>
<p>We call it grip and it lets us drive fearlessly around hard corners very fast.</p>
</blockquote>
<p>— <a href="https://www.reddit.com/r/programming/comments/7ugm8e/c2_c_with_cleaner_syntax_a_module_system_no/dtkde2s/">u/asmx85 on reddit</a>.</p>
<p>Thanks to <a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328/488">JustAPerson for the suggestion</a>!</p>
<p><a href="http://users.rust-lang.org/t/twir-quote-of-the-week/328">Submit your quotes for next week</a>!</p>
<p><em>This Week in Rust is edited by: <a href="https://github.com/nasa42">nasa42</a> and <a href="https://github.com/llogiq">llogiq</a>.</em></p>Tue, 06 Feb 2018 05:00:00 +0000TWiR ContributorsAir Mozilla: Mozilla Weekly Project Meeting, 05 Feb 2018https://air.mozilla.org/mozilla-weekly-project-meeting-20180205/https://air.mozilla.org/mozilla-weekly-project-meeting-20180205/
<p>
<img alt="Mozilla Weekly Project Meeting" class="wp-post-image" height="90" src="https://air.cdn.mozilla.net/media/cache/e9/4f/e94fbd7f8df916c75a60e63a85b9168c.png" width="160" />
The Monday Project Meeting
</p>Mon, 05 Feb 2018 19:00:00 +0000Air MozillaEmma Irwin: (New) Diversity & Inclusion In Open Source — Community Call!http://tiptoes.ca/?p=3330http://tiptoes.ca/new-diversity-inclusion-in-open-source%e2%80%8a-%e2%80%8acommunity-call/
<section class="section section--body">
<div class="section-divider"> <a href="http://tiptoes.ca/new-diversity-inclusion-in-open-source%e2%80%8a-%e2%80%8acommunity-call/word_cloud_generator_-_2018-02-05_04-36-51/" rel="attachment wp-att-3332"><img alt="" class="size-full wp-image-3332 aligncenter" height="606" src="http://tiptoes.ca/wp-content/uploads/2018/02/Word_Cloud_Generator_-_2018-02-05_04.36.51.png" width="1016" /></a></div>
<section class="section section--body">
<div class="section-divider">
<hr class="section-divider" />
</div>
<div class="section-content">
<div class="section-inner sectionLayout--insetColumn">
<p class="graf graf--p">Last year, after three months of qualitative and quantitative research, we published a series of <a class="markup--anchor markup--p-anchor" href="https://opensource.com/article/17/9/diversity-and-inclusion-innovation" rel="noopener" target="_blank">recommendations for D&amp;I in open source</a>. Since this time, we’ve been busy implementing many of those in our work — like these <a class="markup--anchor markup--p-anchor" href="https://discourse.mozilla.org/t/what-s-next-for-volunteer-leadership-in-2018/25091" rel="noopener" target="_blank">new principles for <strong class="markup--strong markup--p-strong">inclusive volunteer leadership</strong></a> , <a class="markup--anchor markup--p-anchor" href="https://github.com/mozilla/diversity/issues/73" rel="noopener" target="_blank">processes for <strong class="markup--strong markup--p-strong">effectively responding</strong> to Community Participation Guideline Reports</a> and investment in <a class="markup--anchor markup--p-anchor" href="https://github.com/mozilla/diversity/issues/53" rel="noopener" target="_blank"><strong class="markup--strong markup--p-strong">Metrics that Matte</strong>r</a> for D&amp;I in <a class="markup--anchor markup--p-anchor" href="https://drnikki.github.io/sphinx-ghpages/index.html" rel="noopener" target="_blank">Open Source</a>. To name only a few.</p>
<h3 class="graf graf--h3">Let’s Work Together!</h3>
<p class="graf graf--p">One thing we heard over, and over again in our research was the belief that to move the needle on diversity in open source — and tech overall,<strong class="markup--strong markup--p-strong"> we must move to be more intentional in our collaboration across projects and communities</strong>.</p>
<p class="graf graf--p">To explore this concept, I’ll be sharing the insights from our recent D&amp;I in FOSS survey in the launch of our <strong class="markup--strong markup--p-strong">first D&amp;I in Open Source Community Call! </strong>February 28th 9AM PST (<a class="markup--anchor markup--p-anchor" href="https://www.timeanddate.com/worldclock/fixedtime.html?iso=20180228T1700" rel="noopener" target="_blank">your time</a>)</p>
<p class="graf graf--p"><em class="markup--em markup--p-em">With over 200 projects represented</em>, we learned a lot… not only from responses, but from the challenge of creating an inclusive survey — with privacy, respect and safety of people at center.</p>
<p class="graf graf--p"><strong class="markup--strong markup--p-strong">Please </strong><a class="markup--anchor markup--p-anchor" href="https://calendly.com/eirwin/d-i-in-open-source-community-call/02-28-2018" rel="noopener" target="_blank"><strong class="markup--strong markup--p-strong">join this first call </strong></a><strong class="markup--strong markup--p-strong">to help shape what comes next. </strong>What are you working on, what do you need help with? What speakers would you like to see invited?</p>
</div>
</div>
</section>
<section class="section section--body">
<div class="section-divider">
<hr class="section-divider" />
</div>
<div class="section-content">
<div class="section-inner sectionLayout--insetColumn">
<p class="graf graf--p"><em class="markup--em markup--p-em">We’ll be running this call using </em><a class="markup--anchor markup--p-anchor" href="https://wiki.mozilla.org/Vidyo" rel="noopener" target="_blank"><em class="markup--em markup--p-em">Vidyo</em></a><em class="markup--em markup--p-em"> (which has video and phone-in), as well as </em><a class="markup--anchor markup--p-anchor" href="https://telegram.org/" rel="noopener" target="_blank"><em class="markup--em markup--p-em">Telegram</em></a><em class="markup--em markup--p-em"> (for those with bandwidth issues, or who prefer text-based interactions). </em><strong class="markup--strong markup--p-strong"><em class="markup--em markup--p-em">You can sign up here for a </em></strong><a class="markup--anchor markup--p-anchor" href="https://calendly.com/eirwin/d-i-in-open-source-community-call/02-28-2018" rel="noopener" target="_blank"><strong class="markup--strong markup--p-strong"><em class="markup--em markup--p-em">calendar invite</em></strong></a><strong class="markup--strong markup--p-strong"><em class="markup--em markup--p-em">. </em></strong><a class="markup--anchor markup--p-anchor" href="https://github.com/mozilla/diversity/blob/master/community_calls/02.27.2018.md" rel="noopener" target="_blank"><em class="markup--em markup--p-em">Agenda outline here</em></a><em class="markup--em markup--p-em">. Please reach out directly to Emma (eirwin @ mozilla dot com)</em></p>
</div>
</div>
</section>
</section>
<p><a class="a2a_button_facebook" href="http://www.addtoany.com/add_to/facebook?linkurl=http%3A%2F%2Ftiptoes.ca%2Fnew-diversity-inclusion-in-open-source%25e2%2580%258a-%25e2%2580%258acommunity-call%2F&amp;linkname=%28New%29%20Diversity%20%26%20Inclusion%20In%20Open%20Source%E2%80%8A%E2%80%94%E2%80%8ACommunity%20Call%21" rel="nofollow" target="_blank" title="Facebook"><img alt="Facebook" height="16" src="http://tiptoes.ca/wp-content/plugins/add-to-any/icons/facebook.png" width="16" /></a><a class="a2a_button_twitter" href="http://www.addtoany.com/add_to/twitter?linkurl=http%3A%2F%2Ftiptoes.ca%2Fnew-diversity-inclusion-in-open-source%25e2%2580%258a-%25e2%2580%258acommunity-call%2F&amp;linkname=%28New%29%20Diversity%20%26%20Inclusion%20In%20Open%20Source%E2%80%8A%E2%80%94%E2%80%8ACommunity%20Call%21" rel="nofollow" target="_blank" title="Twitter"><img alt="Twitter" height="16" src="http://tiptoes.ca/wp-content/plugins/add-to-any/icons/twitter.png" width="16" /></a><a class="a2a_button_google_plus" href="http://www.addtoany.com/add_to/google_plus?linkurl=http%3A%2F%2Ftiptoes.ca%2Fnew-diversity-inclusion-in-open-source%25e2%2580%258a-%25e2%2580%258acommunity-call%2F&amp;linkname=%28New%29%20Diversity%20%26%20Inclusion%20In%20Open%20Source%E2%80%8A%E2%80%94%E2%80%8ACommunity%20Call%21" rel="nofollow" target="_blank" title="Google+"><img alt="Google+" height="16" src="http://tiptoes.ca/wp-content/plugins/add-to-any/icons/google_plus.png" width="16" /></a><a class="a2a_dd a2a_target addtoany_share_save" href="https://www.addtoany.com/share#url=http%3A%2F%2Ftiptoes.ca%2Fnew-diversity-inclusion-in-open-source%25e2%2580%258a-%25e2%2580%258acommunity-call%2F&amp;title=%28New%29%20Diversity%20%26%20Inclusion%20In%20Open%20Source%E2%80%8A%E2%80%94%E2%80%8ACommunity%20Call%21" id="wpa2a_2">Share</a></p>Mon, 05 Feb 2018 15:13:13 +0000EmmaQMO: Firefox 59 Beta 6 Testday Resultshttps://quality.mozilla.org/?p=50059https://quality.mozilla.org/2018/02/firefox-59-beta-6-testday-results/
<p>Hello everyone,</p>
<p>As you may already know, last Friday – <strong>February 2nd</strong> – we held a new Testday event, for <strong>Firefox 59 Beta 6</strong>.</p>
<p>Thank you Adam, Nilam and Gabriela for helping us make Mozilla a better place.</p>
<p>From <strong>India QA Community team</strong>: <i>Mohammed Adam</i>, <i>Aishwarya</i>, <i> Fahima Zulfath A</i>. and <em>Surentharan.R.A.</em></p>
<p>Results:<br />
– several test cases executed for <b>Form Autofill V2 </b><b> </b>and <b> Firefox address bar search suggestions</b> features.</p>
<p>– 2 bugs verified: <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1038695">1038695</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1115976">1115976</a></p>
<p>– 1 new bug filed: <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1435590">1435590</a>.</p>
<p>Thanks for another successful testday <img alt="🙂" class="wp-smiley" src="https://s.w.org/images/core/emoji/2.4/72x72/1f642.png" style="height: 1em;" /></p>
<p>We hope to see you all in our next events, all the details will be posted on QMO!</p>Mon, 05 Feb 2018 13:36:56 +0000Petruta RasaMozilla VR Blog: A-Painter performance optimizations6c168da9-9c75-4edc-a284-89715e4f6ff4https://blog.mozvr.com/a-painter-performance-optimizations/
<h3>Introduction</h3>
<img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/Screen-Shot-2018-02-02-at-12.50.25.png" /><p>A-Painter was the first demo we made using A-Frame. It was released more than a year ago, and it’s still one of the most popular WebVR experiences shown at meetups and exhibitions. </p>
<p>We wanted to show that the browser can deliver native like VR experiences and also push the limits of what A-Frame was able to do at the time. We’ve seen A-Painter being used more and more by professional artists and programmers that test the limits and extend its capabilities. Performance is the bottleneck that people first hit with moderately complex drawings, due to the increased number of strokes and geometry. On collaborative drawing experiences performance degrades even faster since you have multiple users adding geometry simultaneously. </p>
<p>Recently we had some bandwidth and rolled up our sleeves to implement some of the optimizations ideas that we had collected in the past (<a href="https://github.com/aframevr/a-painter/issues/222">Issue #222</a>, <a href="https://github.com/aframevr/a-painter/pull/241">PR #241</a>).</p>
<h3>Draw calls simplified</h3>
<p>There can be several causes of bad performance in your graphics application but looking at the number of draw calls it is a good starting point to investigate. . <br />
A draw call is, as its name indicates, a call to a drawing function on the graphics API with the geometry and the material properties that we want to render. In WebGL it could be a call to gl.drawElements or gl.drawArrays. These calls are expensive so we want to keep them as low as possible.</p>
<p>We will use the <a href="https://aframe.io/a-painter/?url=https://ucarecdn.com/962b242b-87a9-422c-b730-febdc470f203/">Balrog scene</a> by <a href="https://twitter.com/feiss">@feiss</a> to measure the impact of the optimizations I’m proposing here. <br />
The following image shows the statistics when rendering this scene on my computer (Windows i7 GTX1080):</p>
<p><img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/pasted-image-0.png" /></p>
<p>We should identify which numbers affect our performance:</p>
<ul>
<li><strong>14 textures</strong>: Every brush that needs a material (lines and stamps) creates its own texture. Instead, they could reuse an atlas with all the textures.</li>
<li><strong>542 entities</strong>: We created one entity per stroke.</li>
<li><strong>454 geometries</strong>: One entity per stroke means also one <code>Object3D</code>, <code>Mesh</code>, <code>BufferGeometry</code> and Material per stroke.</li>
<li><strong>450 calls</strong>: The number of draw calls we would like to optimize.</li>
</ul>
<p>To reduce the number of draw calls we should:</p>
<ul>
<li>Reduce the number of textures.</li>
<li>Reduce the number of materials (same reason).</li>
<li>Reduce the number of geometries by merging all the meshes we can into a bigger mesh, so we could use just one draw call to paint multiple geometries.</li>
</ul>
<p>In the following sections we will go through these steps explaining how we could apply them to our application.</p>
<h3>Materials</h3>
<h4>Atlas</h4>
<p>The first step is to reduce the number of materials created as switching from one material to another will cause a new draw call.</p>
<p>We will start creating a new atlas containing all the textures for each brush, using the spritesheet.js tool, adding a new npm command called <code>atlas</code> using <code>spritesheet-js</code> to pack them:</p>
<pre><code>"atlas": "spritesheet-js --name brush_atlas --path assets/images brushes/*.png"
</code></pre>
<p>If we now execute <code>npm run atlas</code>, it will create a png image with all our brush textures and a JSON file with the needed information to locate them inside the atlas.</p>
<p><img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/a-painter-optimization-1.png" /></p>
<p>The generated JSON is very easy to parse and includes the size of the generated atlas (<code>meta.size</code>) and the list of images included with their position on the atlas (<code>frames</code>).</p>
<pre><code class="language-javascript">{
"meta": {
"image": "brush_atlas.png",
"size": {"w":3584,"h":2944},
"scale": "1"
},
"frames": {
"stamp_grass.png":
{
"frame": {"x":0,"y":128,"w":1536,"h":512},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":1536,"h":512},
"sourceSize": {"w":1536,"h":512}
},
"lines4.png":
{
"frame": {"x":0,"y":0,"w":2048,"h":128},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":2048,"h":128},
"sourceSize": {"w":2048,"h":128}
},
"stamp_fur2.png":
{
"frame": {"x":0,"y":640,"w":1536,"h":512},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":1536,"h":512},
"sourceSize": {"w":1536,"h":512}
},
</code></pre>
<p>Now we need a simple way to convert the local UV coordinates to the new coordinates inside the atlas space. To ease this task we will create a helper class called Atlas that will parse the generated JSON and will provide two functions to convert our UV coordinates.</p>
<pre><code class="language-javascript">function Atlas () {
this.map = new THREE.TextureLoader().load('assets/images/' + AtlasJSON.meta.image);
}
Atlas.prototype = {
getUVConverters (filename) {
if (filename) {
filename = filename.replace('brushes/', '');
return {
convertU (u) {
var totalSize = AtlasJSON.meta.size;
var data = AtlasJSON.frames[filename];
if (u &gt; 1 || u &lt; 0) {
u = 0;
}
return data.frame.x / totalSize.w + u * data.frame.w / totalSize.w;
},
convertV (v) {
var totalSize = AtlasJSON.meta.size;
var data = AtlasJSON.frames[filename];
if (v &gt; 1 || v &lt; 0) {
v = 0;
}
return 1 - (data.frame.y / totalSize.h + v * data.frame.h / totalSize.h);
}
};
} else {
return {
convertU (u) { return u; },
convertV (v) { return v; }
};
}
}
};
</code></pre>
<p>Using this helper we could easily convert the following code:</p>
<pre><code class="language-javascript">material.map = “lines1.png”;
uv[0].set(0, 0);
uv[1].set(1, 1);
</code></pre>
<p>Into this: </p>
<pre><code class="language-javascript">material.map = “atlas.png”;
converter = atlas.getUVConverters(“lines1.png”);
uvs[0].set( converter.convertU(0), converter.convertV(0) );
uvs[1].set( converter.convertU(1), converter.convertV(1) );
</code></pre>
<p>Thanks to the atlas technique, the number of textures in our app is reduced from 30 to 1.</p>
<h5>Vertex colors</h5>
<p>But we still have a problem: each stroke has a material and a custom value for <code>material.color</code>, making impossible to share the same material across all the strokes. <br />
Fortunately, reusing the same material when just changing the color has a very simple solution: vertex colors. <br />
We can define a specific color for each vertex of the geometry with vertex colors, that will be multiplied by the material color that is applied to the whole geometry. Since this value will be pure white <code>(1, 1, 1)</code>, vertex colors will remain unaltered (We could any color other than white to tint the vertex colors).</p>
<p>In order to do that, we should set up the material to use vertex colors...</p>
<pre><code class="language-javascript">mainMaterial.vertexColors = THREE.VertexColors;
</code></pre>
<p>...and create a new color buffer attribute for our mesh:</p>
<pre><code class="language-javascript">var colors = new Float32Array(this.maxBufferSize * 3);
geometry.addAttribute('color', new THREE.BufferAttribute(colors, 3).setDynamic(true));
// Set everything red
var color = [1, 0 ,0];
for (var i=0;i &lt; numVertices; i++) {
colors[3 * i] = color[0];
colors[3 * i + 1] = color[1];
colors[3 * i + 2] = color[2];
}
geometry.attributes.uv.needsUpdate = true;
</code></pre>
<p>Thus, the number of materials is reduced from the number of individual strokes (hundreds in one painting) to just 4: two physically-based render materials (<code>THREE.MeshStandardMaterial</code>), and two <code>THREE.MeshBasicMaterial</code>: one textured and one for solid colors.</p>
<h4>Reducing the number of A-Frame entities</h4>
<p>Initially every stroke generated a new entity, and each entity contains a mesh that it’s rendered separately on its own draw call. Our goal is to reduce these entities and meshes by merging all the strokes into one big mesh that could be rendered with just one draw call.</p>
<p>We were creating one entity for each stroke appending it to a <code>&lt;a-entity class=”a-drawing”&gt;</code> root entity:</p>
<pre><code class="language-javascript">// Get the root entity
var stroke = brushSystem.startNewStroke();
// Get the root entity
var drawing = document.querySelector('.a-drawing');
// Create a new entity for the current stroke
var entity = document.createElement('a-entity');
entity.className = "a-stroke";
drawing.appendChild(entity);
entity.setObject3D('mesh', stroke.object3D);
stroke.entity = entity;
</code></pre>
<p>We could remove the entities per stroke overhead by adding directly the new stroke mesh to the root <a href="https://aframe.io/docs/0.7.0/core/entity.html#object3d">entity’s Object3D</a>:</p>
<pre><code class="language-javascript">var stroke = brushSystem.startNewStroke();
// Create a new entity for the current stroke
drawing.object3D.add(stroke.object3D);
</code></pre>
<p>and we would need to modify some pieces of code like the “undo” functionality to just remove the object3D instead of the entity. Although this is just a temporary step before we could get rid of these object3D per stroke by merging all of them and save many draw calls by sharing BufferGeometries.</p>
<h4>Shared BufferGeometry</h4>
<p>We have already reduced the number of textures, materials and entities but we still have an <code>Object -&gt; Mesh -&gt; BufferGeometry</code> per stroke, so we haven’t reduced yet the number of draw calls. <br />
Ideally it would be better to have a very big BufferGeometry and keep adding vertices to it on each stroke, and just send it to the GPU saving plenty of draw calls.</p>
<p>For this purpose we will create a class called SharedBufferGeometry that will be instantiated by just passing the type of material we want to use.</p>
<pre><code class="language-javascript">function SharedBufferGeometry (material) {
this.material = material;
this.maxBufferSize = 1000000; // an arbitrary high enough number of vertices
this.geometries = [];
this.currentGeometry = null;
this.addBuffer();
}
</code></pre>
<p><code>addBuffer</code> will create a Mesh with a BufferGeometry with the needed attributes and it will add it to the list of meshes the root Object3D has.
It will contain some helper functions so we don’t need to care about indices or buffer overflows as it should be handed automatically.</p>
<pre><code class="language-javascript"> addVertex: function (x, y, z) {
var buffer = this.currentGeometry.attributes.position;
if (this.idx.position === buffer.count) {
this.addBuffer(true);
buffer = this.currentGeometry.attributes.position;
}
buffer.setXYZ(this.idx.position++, x, y, z);
},
addColor: function (r, g, b) {
this.currentGeometry.attributes.color.setXYZ(this.idx.color++, r, g, b);
},
addNormal: function (x, y, z) {
this.currentGeometry.attributes.normal.setXYZ(this.idx.normal++, x, y, z);
},
addUV: function (u, v) {
this.currentGeometry.attributes.uv.setXY(this.idx.uv++, u, v);
},
</code></pre>
<p>Actually we’ll need more than one BufferGeometry because some brushes don’t have textures so they don’t need UV attributes and/or are not affected by lighting so no need for normal attribute either. <br />
We'll create <code>SharedBufferGeometryManager</code>to handle all this buffers:</p>
<pre><code class="language-javascript">function SharedBufferGeometryManager () {
this.sharedBuffers = {};
}
SharedBufferGeometryManager.prototype = {
addSharedBuffer: function (name, material) {
var bufferGeometry = new SharedBufferGeometry(material);
this.sharedBuffers[name] = bufferGeometry;
},
getSharedBuffer: function (name) {
return this.sharedBuffers[name];
}
};
</code></pre>
<p>We will initialize the buffers by calling <code>addSharedBuffer</code> with the different types of materials we’ll be using:</p>
<pre><code class="language-javascript">sharedBufferGeometryManager.addSharedBuffer(‘unlit’, unlitMaterial);
sharedBufferGeometryManager.addSharedBuffer(‘unlitTextured’, unlitTexturedMaterial);
sharedBufferGeometryManager.addSharedBuffer(‘PBR’, pbrMaterial);
sharedBufferGeometryManager.addSharedBuffer(PBRTextured’, pbrTexturedMaterial);
</code></pre>
<p>And we will be ready to use them:</p>
<pre><code class="language-javascript">var sharedBuffer = sharedBufferGeometryManager.get(‘PBR’);
sharedBuffer.addVertex(0, 1, 0);
sharedBuffer.addVertex(1, 1, 0);
sharedBuffer.addUV(0, 0);
</code></pre>
<p>As we are storing several meshes without any connection we’ll be using single triangle soup. That means we’ll store 3 vertices for each triangle without sharing any of them. It will increase the bandwidth and memory requirements as we’re storing (<code>NUM_POINTS_PER_STROKE</code> * 2 * 3) floats for each stroke. <br />
In the case of the Balrog scene using this method our final buffer will have 406.782 floats.</p>
<h4>Triangle strips</h4>
<p>In order to reduce the size of our BufferGeometry attributes, we could switch from triangle soup to triangle strips. Although using triangle strips in some situations could be challenging, using it when painting lines/ribbons is pretty straightforward: we just need to keep adding two new vertices at a time as the line grows.</p>
<p><img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/a-painter-optimization-2.png" /></p>
<p>Using triangle strips we’ll reduce the size of the position attribute array drastically. </p>
<ul>
<li><strong>Triangle soup:</strong> <code>NUMBER_OF_STROKE_POINTS</code> * 2 (<code>triangles</code>) * 3 (<code>vertices</code>) * 3 (<code>xyz</code>)</li>
<li><strong>Triangle strip:</strong> <code>NUMBER_OF_STROKE_POINTS</code> * 2 (<code>vertices</code>)</li>
</ul>
<p>As an example here are the position array sizes from the Balrog example:</p>
<ul>
<li><strong>Triangle soup:</strong> 135.594.</li>
<li><strong>Triangle strip:</strong> 47.248.</li>
</ul>
<p>At first it looks like an easy win, but if we look carefully we will realize that we need to fix some issues: we are sharing the same buffer to draw several unconnected strokes, but every time we add a new vertice it will create a new triangle using the two previous vertices, so all the strokes will be hideously connected:</p>
<p><img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/a-painter-optimization-3.png" /></p>
<p>We need a way to tell WebGL to skip that triangles, and although WebGL doesn’t support <a href="https://www.khronos.org/opengl/wiki/Vertex_Rendering#Primitive_Restart">primitive restart</a> we can do our own “primitive restart” by creating a degenerated triangle, which is a triangle with no area that is discarded by the GPU.</p>
<p>To create these degenerated triangles to separate two strokes we will just duplicate the last vertex from the first stroke and duplicate the first vertex on the next stroke.</p>
<p><img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/a-painter-optimization-4.png" /></p>
<p>So I create a <code>restartPrimitive()</code> function on the <code>SharedBufferGeometry</code> to duplicate the last vertex of the latest stroke, and once the first point of the next stroke is added, it has to be duplicated too.</p>
<p>The hardest part here is when working with indices as we need to keep track of the degenerated vertices so these position offsets have to be applied to the texture coordinates, colors and normals, too.</p>
<p>You can take a look at the <a href="https://github.com/aframevr/a-painter/blob/master/src/brushes/line.js">Line Brush</a> to see the whole implementation.</p>
<h3>Results</h3>
<p>In the following table we could see the statistics of the Balrog scene before and after the exposed optimizations:</p>
<p>Please note that these numbers also include common scene objects: floor, sky, controllers…</p>
<p>If we launch devtools we can see that we drastically reduced the animation frame time:</p>
<p>Before: <br />
<img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/frametime-bad.png" /></p>
<p>After:</p>
<p><img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/frametime-good.png" /></p>
<p>Looking at the performance graphs it’s visible how the GC hit because of the allocations we did on the render loop. Also we’ve reduced considerably the CPU usage.</p>
<p>Before:</p>
<p><img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/perf-bad.png" /></p>
<p>After: <br />
<img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/perf-good.png" /></p>
<p>The performance differences are visible both on Chrome and Firefox. For example the following is a graph of the latter where the fps drop to <strong>2fps</strong> almost every two seconds.</p>
<p>Before: <br />
<img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/ffox-bad.png" /></p>
<p>After: <br />
<img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/ffox-good.png" /></p>
<p>As demonstrated, the optimizations implemented have a major impact on A-Painter performance without adding too much complexity to the code. VR mode benefits the most. You can now paint for a long time without getting motion sickness: That’s a pretty good usability enhancement.</p>
<h3>Further improvements</h3>
<p>There are still many other optimizations that can further improve performance:</p>
<ul>
<li>Find an alternative for a bug (or <a href="https://github.com/mrdoob/three.js/pull/11979">feature</a>) when computing the bounding box or sphere when using BufferGeometry that will include always the unused vertices from the array (origin vertices at (0,0,0)) so the frustum culling won’t be as effective as it should.</li>
<li>Use <a href="https://en.wikipedia.org/wiki/Geometry_instancing">geometry instancing</a> on brushes that paint spheres and cubes, so we don’t create new geometry on each stroke but reuse the previously created geometry.</li>
<li>Use a <a href="https://en.wikipedia.org/wiki/Level_of_detail">LOD</a> system to reduce the complexity of drawings based on distance. This could be useful if used on a big open environment like a social AR app.</li>
<li>Also on big open spaces it could be useful to implement some kind of space partitioning (<a href="https://en.wikipedia.org/wiki/Octree">Octrees</a> or <a href="https://en.wikipedia.org/wiki/Bounding_volume_hierarchy">BVH</a>) to improve culling and interaction on each stroke.</li>
</ul>Mon, 05 Feb 2018 13:08:00 +0000Fernando SerranoMozilla VR Blog: A-Painter performance optimizations5a85661efb0518001815dc06https://blog.mozvr.com/a-painter-performance-optimizations/
<div class="kg-card-markdown"><h3>Introduction</h3>
<img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/Screen-Shot-2018-02-02-at-12.50.25.png" /><p>A-Painter was the first demo we made using A-Frame. It was released more than a year ago, and it’s still one of the most popular WebVR experiences shown at meetups and exhibitions.</p>
<p>We wanted to show that the browser can deliver native like VR experiences and also push the limits of what A-Frame was able to do at the time. We’ve seen A-Painter being used more and more by professional artists and programmers that test the limits and extend its capabilities. Performance is the bottleneck that people first hit with moderately complex drawings, due to the increased number of strokes and geometry. On collaborative drawing experiences performance degrades even faster since you have multiple users adding geometry simultaneously.</p>
<p>Recently we had some bandwidth and rolled up our sleeves to implement some of the optimizations ideas that we had collected in the past (<a href="https://github.com/aframevr/a-painter/issues/222">Issue #222</a>, <a href="https://github.com/aframevr/a-painter/pull/241">PR #241</a>).</p>
<h3>Draw calls simplified</h3>
<p>There can be several causes of bad performance in your graphics application but looking at the number of draw calls it is a good starting point to investigate. .<br />
A draw call is, as its name indicates, a call to a drawing function on the graphics API with the geometry and the material properties that we want to render. In WebGL it could be a call to gl.drawElements or gl.drawArrays. These calls are expensive so we want to keep them as low as possible.</p>
<p>We will use the <a href="https://aframe.io/a-painter/?url=https://ucarecdn.com/962b242b-87a9-422c-b730-febdc470f203/">Balrog scene</a> by <a href="https://twitter.com/feiss">@feiss</a> to measure the impact of the optimizations I’m proposing here.<br />
The following image shows the statistics when rendering this scene on my computer (Windows i7 GTX1080):</p>
<p><img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/pasted-image-0.png" /></p>
<p>We should identify which numbers affect our performance:</p>
<ul>
<li><strong>14 textures</strong>: Every brush that needs a material (lines and stamps) creates its own texture. Instead, they could reuse an atlas with all the textures.</li>
<li><strong>542 entities</strong>: We created one entity per stroke.</li>
<li><strong>454 geometries</strong>: One entity per stroke means also one <code>Object3D</code>, <code>Mesh</code>, <code>BufferGeometry</code> and Material per stroke.</li>
<li><strong>450 calls</strong>: The number of draw calls we would like to optimize.</li>
</ul>
<p>To reduce the number of draw calls we should:</p>
<ul>
<li>Reduce the number of textures.</li>
<li>Reduce the number of materials (same reason).</li>
<li>Reduce the number of geometries by merging all the meshes we can into a bigger mesh, so we could use just one draw call to paint multiple geometries.</li>
</ul>
<p>In the following sections we will go through these steps explaining how we could apply them to our application.</p>
<h3>Materials</h3>
<h4>Atlas</h4>
<p>The first step is to reduce the number of materials created as switching from one material to another will cause a new draw call.</p>
<p>We will start creating a new atlas containing all the textures for each brush, using the spritesheet.js tool, adding a new npm command called <code>atlas</code> using <code>spritesheet-js</code> to pack them:</p>
<pre><code>"atlas": "spritesheet-js --name brush_atlas --path assets/images brushes/*.png"
</code></pre>
<p>If we now execute <code>npm run atlas</code>, it will create a png image with all our brush textures and a JSON file with the needed information to locate them inside the atlas.</p>
<p><img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/a-painter-optimization-1.png" /></p>
<p>The generated JSON is very easy to parse and includes the size of the generated atlas (<code>meta.size</code>) and the list of images included with their position on the atlas (<code>frames</code>).</p>
<pre><code class="language-javascript">{
"meta": {
"image": "brush_atlas.png",
"size": {"w":3584,"h":2944},
"scale": "1"
},
"frames": {
"stamp_grass.png":
{
"frame": {"x":0,"y":128,"w":1536,"h":512},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":1536,"h":512},
"sourceSize": {"w":1536,"h":512}
},
"lines4.png":
{
"frame": {"x":0,"y":0,"w":2048,"h":128},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":2048,"h":128},
"sourceSize": {"w":2048,"h":128}
},
"stamp_fur2.png":
{
"frame": {"x":0,"y":640,"w":1536,"h":512},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":1536,"h":512},
"sourceSize": {"w":1536,"h":512}
},
</code></pre>
<p>Now we need a simple way to convert the local UV coordinates to the new coordinates inside the atlas space. To ease this task we will create a helper class called Atlas that will parse the generated JSON and will provide two functions to convert our UV coordinates.</p>
<pre><code class="language-javascript">function Atlas () {
this.map = new THREE.TextureLoader().load('assets/images/' + AtlasJSON.meta.image);
}
Atlas.prototype = {
getUVConverters (filename) {
if (filename) {
filename = filename.replace('brushes/', '');
return {
convertU (u) {
var totalSize = AtlasJSON.meta.size;
var data = AtlasJSON.frames[filename];
if (u &gt; 1 || u &lt; 0) {
u = 0;
}
return data.frame.x / totalSize.w + u * data.frame.w / totalSize.w;
},
convertV (v) {
var totalSize = AtlasJSON.meta.size;
var data = AtlasJSON.frames[filename];
if (v &gt; 1 || v &lt; 0) {
v = 0;
}
return 1 - (data.frame.y / totalSize.h + v * data.frame.h / totalSize.h);
}
};
} else {
return {
convertU (u) { return u; },
convertV (v) { return v; }
};
}
}
};
</code></pre>
<p>Using this helper we could easily convert the following code:</p>
<pre><code class="language-javascript">material.map = “lines1.png”;
uv[0].set(0, 0);
uv[1].set(1, 1);
</code></pre>
<p>Into this:</p>
<pre><code class="language-javascript">material.map = “atlas.png”;
converter = atlas.getUVConverters(“lines1.png”);
uvs[0].set( converter.convertU(0), converter.convertV(0) );
uvs[1].set( converter.convertU(1), converter.convertV(1) );
</code></pre>
<p>Thanks to the atlas technique, the number of textures in our app is reduced from 30 to 1.</p>
<h5>Vertex colors</h5>
<p>But we still have a problem: each stroke has a material and a custom value for <code>material.color</code>, making impossible to share the same material across all the strokes.<br />
Fortunately, reusing the same material when just changing the color has a very simple solution: vertex colors.<br />
We can define a specific color for each vertex of the geometry with vertex colors, that will be multiplied by the material color that is applied to the whole geometry. Since this value will be pure white <code>(1, 1, 1)</code>, vertex colors will remain unaltered (We could any color other than white to tint the vertex colors).</p>
<p>In order to do that, we should set up the material to use vertex colors...</p>
<pre><code class="language-javascript">mainMaterial.vertexColors = THREE.VertexColors;
</code></pre>
<p>...and create a new color buffer attribute for our mesh:</p>
<pre><code class="language-javascript">var colors = new Float32Array(this.maxBufferSize * 3);
geometry.addAttribute('color', new THREE.BufferAttribute(colors, 3).setDynamic(true));
// Set everything red
var color = [1, 0 ,0];
for (var i=0;i &lt; numVertices; i++) {
colors[3 * i] = color[0];
colors[3 * i + 1] = color[1];
colors[3 * i + 2] = color[2];
}
geometry.attributes.uv.needsUpdate = true;
</code></pre>
<p>Thus, the number of materials is reduced from the number of individual strokes (hundreds in one painting) to just 4: two physically-based render materials (<code>THREE.MeshStandardMaterial</code>), and two <code>THREE.MeshBasicMaterial</code>: one textured and one for solid colors.</p>
<h4>Reducing the number of A-Frame entities</h4>
<p>Initially every stroke generated a new entity, and each entity contains a mesh that it’s rendered separately on its own draw call. Our goal is to reduce these entities and meshes by merging all the strokes into one big mesh that could be rendered with just one draw call.</p>
<p>We were creating one entity for each stroke appending it to a <code>&lt;a-entity class=”a-drawing”&gt;</code> root entity:</p>
<pre><code class="language-javascript">// Get the root entity
var stroke = brushSystem.startNewStroke();
// Get the root entity
var drawing = document.querySelector('.a-drawing');
// Create a new entity for the current stroke
var entity = document.createElement('a-entity');
entity.className = "a-stroke";
drawing.appendChild(entity);
entity.setObject3D('mesh', stroke.object3D);
stroke.entity = entity;
</code></pre>
<p>We could remove the entities per stroke overhead by adding directly the new stroke mesh to the root <a href="https://aframe.io/docs/0.7.0/core/entity.html#object3d">entity’s Object3D</a>:</p>
<pre><code class="language-javascript">var stroke = brushSystem.startNewStroke();
// Create a new entity for the current stroke
drawing.object3D.add(stroke.object3D);
</code></pre>
<p>and we would need to modify some pieces of code like the “undo” functionality to just remove the object3D instead of the entity. Although this is just a temporary step before we could get rid of these object3D per stroke by merging all of them and save many draw calls by sharing BufferGeometries.</p>
<h4>Shared BufferGeometry</h4>
<p>We have already reduced the number of textures, materials and entities but we still have an <code>Object -&gt; Mesh -&gt; BufferGeometry</code> per stroke, so we haven’t reduced yet the number of draw calls.<br />
Ideally it would be better to have a very big BufferGeometry and keep adding vertices to it on each stroke, and just send it to the GPU saving plenty of draw calls.</p>
<p>For this purpose we will create a class called SharedBufferGeometry that will be instantiated by just passing the type of material we want to use.</p>
<pre><code class="language-javascript">function SharedBufferGeometry (material) {
this.material = material;
this.maxBufferSize = 1000000; // an arbitrary high enough number of vertices
this.geometries = [];
this.currentGeometry = null;
this.addBuffer();
}
</code></pre>
<p><code>addBuffer</code> will create a Mesh with a BufferGeometry with the needed attributes and it will add it to the list of meshes the root Object3D has.<br />
It will contain some helper functions so we don’t need to care about indices or buffer overflows as it should be handed automatically.</p>
<pre><code class="language-javascript"> addVertex: function (x, y, z) {
var buffer = this.currentGeometry.attributes.position;
if (this.idx.position === buffer.count) {
this.addBuffer(true);
buffer = this.currentGeometry.attributes.position;
}
buffer.setXYZ(this.idx.position++, x, y, z);
},
addColor: function (r, g, b) {
this.currentGeometry.attributes.color.setXYZ(this.idx.color++, r, g, b);
},
addNormal: function (x, y, z) {
this.currentGeometry.attributes.normal.setXYZ(this.idx.normal++, x, y, z);
},
addUV: function (u, v) {
this.currentGeometry.attributes.uv.setXY(this.idx.uv++, u, v);
},
</code></pre>
<p>Actually we’ll need more than one BufferGeometry because some brushes don’t have textures so they don’t need UV attributes and/or are not affected by lighting so no need for normal attribute either.<br />
We'll create <code>SharedBufferGeometryManager</code>to handle all this buffers:</p>
<pre><code class="language-javascript">function SharedBufferGeometryManager () {
this.sharedBuffers = {};
}
SharedBufferGeometryManager.prototype = {
addSharedBuffer: function (name, material) {
var bufferGeometry = new SharedBufferGeometry(material);
this.sharedBuffers[name] = bufferGeometry;
},
getSharedBuffer: function (name) {
return this.sharedBuffers[name];
}
};
</code></pre>
<p>We will initialize the buffers by calling <code>addSharedBuffer</code> with the different types of materials we’ll be using:</p>
<pre><code class="language-javascript">sharedBufferGeometryManager.addSharedBuffer(‘unlit’, unlitMaterial);
sharedBufferGeometryManager.addSharedBuffer(‘unlitTextured’, unlitTexturedMaterial);
sharedBufferGeometryManager.addSharedBuffer(‘PBR’, pbrMaterial);
sharedBufferGeometryManager.addSharedBuffer(PBRTextured’, pbrTexturedMaterial);
</code></pre>
<p>And we will be ready to use them:</p>
<pre><code class="language-javascript">var sharedBuffer = sharedBufferGeometryManager.get(‘PBR’);
sharedBuffer.addVertex(0, 1, 0);
sharedBuffer.addVertex(1, 1, 0);
sharedBuffer.addUV(0, 0);
</code></pre>
<p>As we are storing several meshes without any connection we’ll be using single triangle soup. That means we’ll store 3 vertices for each triangle without sharing any of them. It will increase the bandwidth and memory requirements as we’re storing (<code>NUM_POINTS_PER_STROKE</code> * 2 * 3) floats for each stroke.<br />
In the case of the Balrog scene using this method our final buffer will have 406.782 floats.</p>
<h4>Triangle strips</h4>
<p>In order to reduce the size of our BufferGeometry attributes, we could switch from triangle soup to triangle strips. Although using triangle strips in some situations could be challenging, using it when painting lines/ribbons is pretty straightforward: we just need to keep adding two new vertices at a time as the line grows.</p>
<p><img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/a-painter-optimization-2.png" /></p>
<p>Using triangle strips we’ll reduce the size of the position attribute array drastically.</p>
<ul>
<li><strong>Triangle soup:</strong> <code>NUMBER_OF_STROKE_POINTS</code> * 2 (<code>triangles</code>) * 3 (<code>vertices</code>) * 3 (<code>xyz</code>)</li>
<li><strong>Triangle strip:</strong> <code>NUMBER_OF_STROKE_POINTS</code> * 2 (<code>vertices</code>)</li>
</ul>
<p>As an example here are the position array sizes from the Balrog example:</p>
<ul>
<li><strong>Triangle soup:</strong> 135.594.</li>
<li><strong>Triangle strip:</strong> 47.248.</li>
</ul>
<p>At first it looks like an easy win, but if we look carefully we will realize that we need to fix some issues: we are sharing the same buffer to draw several unconnected strokes, but every time we add a new vertice it will create a new triangle using the two previous vertices, so all the strokes will be hideously connected:</p>
<p><img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/a-painter-optimization-3.png" /></p>
<p>We need a way to tell WebGL to skip that triangles, and although WebGL doesn’t support <a href="https://www.khronos.org/opengl/wiki/Vertex_Rendering#Primitive_Restart">primitive restart</a> we can do our own “primitive restart” by creating a degenerated triangle, which is a triangle with no area that is discarded by the GPU.</p>
<p>To create these degenerated triangles to separate two strokes we will just duplicate the last vertex from the first stroke and duplicate the first vertex on the next stroke.</p>
<p><img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/a-painter-optimization-4.png" /></p>
<p>So I create a <code>restartPrimitive()</code> function on the <code>SharedBufferGeometry</code> to duplicate the last vertex of the latest stroke, and once the first point of the next stroke is added, it has to be duplicated too.</p>
<p>The hardest part here is when working with indices as we need to keep track of the degenerated vertices so these position offsets have to be applied to the texture coordinates, colors and normals, too.</p>
<p>You can take a look at the <a href="https://github.com/aframevr/a-painter/blob/master/src/brushes/line.js">Line Brush</a> to see the whole implementation.</p>
<h3>Results</h3>
<p>In the following table we could see the statistics of the Balrog scene before and after the exposed optimizations:</p>
<p>Please note that these numbers also include common scene objects: floor, sky, controllers…</p>
<p>If we launch devtools we can see that we drastically reduced the animation frame time:</p>
<p>Before:<br />
<img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/frametime-bad.png" /></p>
<p>After:</p>
<p><img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/frametime-good.png" /></p>
<p>Looking at the performance graphs it’s visible how the GC hit because of the allocations we did on the render loop. Also we’ve reduced considerably the CPU usage.</p>
<p>Before:</p>
<p><img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/perf-bad.png" /></p>
<p>After:<br />
<img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/perf-good.png" /></p>
<p>The performance differences are visible both on Chrome and Firefox. For example the following is a graph of the latter where the fps drop to <strong>2fps</strong> almost every two seconds.</p>
<p>Before:<br />
<img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/ffox-bad.png" /></p>
<p>After:<br />
<img alt="A-Painter performance optimizations" src="https://blog.mozvr.com/content/images/2018/02/ffox-good.png" /></p>
<p>As demonstrated, the optimizations implemented have a major impact on A-Painter performance without adding too much complexity to the code. VR mode benefits the most. You can now paint for a long time without getting motion sickness: That’s a pretty good usability enhancement.</p>
<h3>Further improvements</h3>
<p>There are still many other optimizations that can further improve performance:</p>
<ul>
<li>Find an alternative for a bug (or <a href="https://github.com/mrdoob/three.js/pull/11979">feature</a>) when computing the bounding box or sphere when using BufferGeometry that will include always the unused vertices from the array (origin vertices at (0,0,0)) so the frustum culling won’t be as effective as it should.</li>
<li>Use <a href="https://en.wikipedia.org/wiki/Geometry_instancing">geometry instancing</a> on brushes that paint spheres and cubes, so we don’t create new geometry on each stroke but reuse the previously created geometry.</li>
<li>Use a <a href="https://en.wikipedia.org/wiki/Level_of_detail">LOD</a> system to reduce the complexity of drawings based on distance. This could be useful if used on a big open environment like a social AR app.</li>
<li>Also on big open spaces it could be useful to implement some kind of space partitioning (<a href="https://en.wikipedia.org/wiki/Octree">Octrees</a> or <a href="https://en.wikipedia.org/wiki/Bounding_volume_hierarchy">BVH</a>) to improve culling and interaction on each stroke.</li>
</ul>
</div>Mon, 05 Feb 2018 13:08:00 +0000Fernando Serrano