Johnathan Nightingale: Home for a Rest |
Earlier today, I sent this note to the global mozilla employees list. It was not an easy send button to push.
===
One of the many, many things Mozilla has taught me over the years is not to bury the lede, so here goes:
March 31 will be my last day at Mozilla.
2014 was an incredible year, and it ended so much better than it started. I’m really proud of what we all accomplished, and I’m so hopeful for Mozilla’s future. But it took a lot out of me. I need to take a break. And as the dust settled on 2014 I realized, for the first time in a while, that I could take one.
You can live the Mozilla mission, feel it in your bones, and still worry about the future; I’ve had those moments over the last 8 years. Maybe you have, too. But Mozilla today is stronger than I’ve seen it in a long time. Our new strategy in search gives us a solid foundation and room to breathe, to experiment, and to make things better for our users and the web. We’re executing better than we ever have, and we’re seeing the shift in our internal numbers, while we wait for the rest of the world to catch up. January’s desktop download numbers are the best they’ve been in years. Accounts are being counted in tens of millions. We’re approaching 100MM downloads on Android. Dev Edition is blowing away targets faster than we can set them; Firefox on iOS doesn’t even exist yet, and already you can debug it with our devtools. Firefox today has a fierce momentum.
None of which will stop the trolls, of course. When this news gets out, I imagine someone will say something stupid. That it’s a Sign Of Doom. Predictable, and dead wrong; it misunderstands us completely. When things looked really rough, at the beginning of 2014, say, and people wanted to write about rats and sinking ships, that’s when I, and all of you, stayed.
You stayed or, in Chris’ case, you came back. And I’ve gotta say, having Chris in the seat is one of the things that gives me the most confidence. I didn’t know what Mozilla would feel like with Chris at the helm, but my CEO in 2014 was a person who pushed me and my team to do better, smarter work, to measure our results, and to keep the human beings who use our stuff at the center of every conversation. In fact, the whole senior team blows me away with their talent and their dedication.
You all do. And it makes me feel like a chump to be packing up in the midst of it all; but it’s time. And no, I haven’t been poached by facebook. I don’t actually know what my next thing will be. I want to take some time to catch up on what’s happened in the world around me. I want to take some time with my kid before she finishes her too-fast sprint to adulthood. I want to plant deeper roots in Toronto tech, which is incredibly exciting right now and may be a place where I can help. And I want a nap.
You are the very best I’ve met. It’s been a privilege to call myself your colleague, and to hand out a business card with the Firefox logo. I’m so immensely grateful for my time at Mozilla, and got so much more done here than I could have hoped. I’m talking with Chris and others about how I can meaningfully stay involved after March as an advisor, alumnus, and cheerleader. Once a Mozillian, always.
Excelsior!
Johnathan
|
Christie Koehler: Fun with git submodules |
Git submodules are amazingly useful. Because they provide a way for you to connect external, separate git repositories they can be used to organize your vim scripts, your dotfiles, or even a whole mediawiki deployment.
As incredibly useful as git submodules are, they can also be a bit confusing to use. This goal of this article is to walk you through the most common git submodule tasks: adding, removing and updating. We’ll also review briefly how to make changes to code you have checked out as a submodule.
I’ve created some practice repositories. Fork submodule-practice if you’d like to follow along. We’ll used these test repositories as submodules:
I’ve used version 2.3.0 of the git client for these examples. If you’re seeing something different, check your version with git --version
.
First, let’s clone our practice repository:
[skade ;) ~/Work] christie$ git clone git@github.com:christi3k/submodule-practice.git Cloning into 'submodule-practice'... remote: Counting objects: 63, done. remote: Compressing objects: 100% (16/16), done. remote: Total 63 (delta 9), reused 0 (delta 0), pack-reused 47 Receiving objects: 100% (63/63), 6.99 KiB | 0 bytes/s, done. Resolving deltas: 100% (25/25), done. Checking connectivity... done.
And then cd into the working directory:
christie$ cd submodule-practice/
Currently, this project has two submodules: furry-octo-nemesis and psychic-avenger.
When we run ls we see directories for these submodules:
[skade ;) ~/Work/submodule-practice (master)] christie$ ll
|
Mike Conley: On unsafe CPOW usage, and “why is my Nightly so sluggish with e10s enabled?” |
If you’ve opened the Browser Console lately while running Nightly with e10s enabled, you might have noticed a warning message – “unsafe CPOW usage” – showing up periodically.
I wanted to talk a little bit about what that means, and what’s being done about it. Brad Lassey already wrote a bit about this, but I wanted to expand upon it (especially since one of my goals this quarter is to get a handle on unsafe CPOW usage in core browser code).
I also wanted to talk about sluggishness that some of our brave Nightly testers with e10s enabled have been experiencing, and where that sluggishness is coming from, and what can be done about it.
“CPOW” stands for “Cross-process Object Wrapper”1, and is part of the glue that has allowed e10s to be enabled on Nightly without requiring a full re-write of the front-end code. It’s also part of the magic that’s allowing a good number of our most popular add-ons to continue working (albeit slowly).
In sum, a CPOW is a way for one process to synchronously access and manipulate something in another process, as if they were running in the same process. Anything that can be considered a JavaScript Object can be represented as a CPOW.
Let me give you an example.
In single-process Firefox, easy and synchronous access to the DOM of web content was more or less assumed. For example, in browser code, one could do this from the scope of a browser window:
let doc = gBrowser.selectedBrowser.contentDocument; let contentBody = doc.body;
Here contentBody corresponds to the element of the document in the currently selected browser. In single-process Firefox, querying for and manipulating web content like this is quick and easy.
In multi-process Firefox, where content is processed and rendered in a completely separate process, how does something like this work? This is where CPOWs come in2.
With a CPOW, one can synchronously access and manipulate these items, just as if they were in the same process. We expose a CPOW for the content document in a remote browser with contentDocumentAsCPOW, so the above could be rewritten as:
let doc = gBrowser.selectedBrowser.contentDocumentAsCPOW; let contentBody = doc.body;
I should point out that contentDocumentAsCPOW and contentWindowAsCPOW are exposed on objects, and that we don’t make every accessor of a CPOW have the “AsCPOW” suffix. This is just our way of making sure that consumers of the contentWindow and contentDocument on the main process side know that they’re probably working with CPOWs3. contentBody.firstChild would also be a CPOW, since CPOWs can only beget more CPOWs.
So for the most part, with CPOWs, we can continue to query and manipulate the of the document loaded in the current browser just like we used to. It’s like an invisible compatibility layer that hops us right over that process barrier.
Great, right?
Well, not really.
CPOWs are really a crutch to help add-ons and browser code exist in this multi-process world, but they’ve got some drawbacks. Most noticeably, there are performance drawbacks.
Have you been noticing sluggish performance on Nightly with e10s? Chances are this is caused by an add-on making use of CPOWs (either knowingly or unknowingly). Because CPOWs are used for synchronous reading and manipulation of objects in other processes, they send messages to other processes to do that work, and block the main process while they wait for a response. We call this “CPOW traffic”, and if you’re experiencing a sluggish Nightly, this is probably where the sluggishness if coming from.
Instead of using CPOWs, add-ons and browser code should be updated to use frame scripts sent over the message manager. Frame scripts cannot block the main process, and can be optimized to send only the bare minimum of information required to perform an action in content and return a result.
Add-ons built with the Add-on SDK should already be using “content scripts” to manipulate content, and therefore should inherit a bunch of fixes from the SDK as e10s gets closer to shipping. These add-ons should not require too many changes. Old-style add-ons, however, will need to be updated to use frame scripts unless they want to be super-sluggish and bog the browser down with CPOW traffic.
“unsafe” might be too strong a word. “unexpected” might be a better term. Brad Lassey laid this out in his blog post already, but I’ll quickly rehash it.
There are two main cases to consider when working with CPOWs:
The first case is what we consider “the good case”. The content process is in a known good state, and its primed to receive IPC traffic (since it’s otherwise just idling). The only bad part about this is the IPC traffic.
The second case is what we consider the bad case. This is when the parent is sending down CPOW messages to the child (by reading or manipulating objects in the content process) when the child process might be off processing other things. This case is far more likely than the first case to cause noticeable performance problems, as the main thread of the content process might be bogged down doing other things before it can handle the CPOW traffic – and the parent will be blocked waiting for the messages to be responded to!
There’s also a more speculative fear that the parent might send down CPOW traffic at a time when it’s “unsafe” to communicate with the content process. There are potentially times when it’s not safe to run JS code in the content process, but CPOWs traffic requires both processes to execute JS. This is a concern that was expressed to me by someone over IRC, and I don’t exactly understand what the implications are – but if somebody wants to comment and let me know, I’ll happily update this post.
So, anyhow, to sum – unsafe CPOW usage is when CPOW traffic is initiated on the parent process side while the content process is not blocked. When this unsafe CPOW usage occurs, we log an “unsafe CPOW usage” message to the Browser Console, along with the script and line number where the CPOW traffic was initiated from.
We need to measure and understand CPOW usage in Firefox, as well as add-ons running in Firefox, and over time we need to reduce this CPOW usage. The priority should be on reducing the “unsafe CPOW usage” CPOWs in core browser code.
If there’s anything that working on the Australis project taught me, it’s that in order to change something, you need to know how to measure it first. That way, you can make sure your efforts are having an effect.
We now have a way of measuring the amount of time that Firefox code and add-ons spend processing CPOW messages. You can look at it yourself – just go to about:compartments.
It’s not the prettiest interface, but it’s a start. The second column is the time processing CPOW traffic, and the higher the number, the longer it’s been doing it. Naturally, we’ll be working to bring those numbers down over time.
As I mentioned, we also list add-ons in about:compartments, so if you’re experiencing a slow Nightly, check out about:compartments and see if there’s an add-on with a high number in the second column. Then, try disabling that add-on to see if your performance problem is reduced.
If so, great! Please file a bug on Bugzilla in this component for the add-on, mention the name of the add-on4, describe the performance problem, and mark it blocking e10s-addons if you can.
We’re hoping to automate this process by exposing some UI that informs the user when an add-on is causing too much CPOW traffic. This will be landing in Nightly near you very soon.
Logging “unsafe CPOW usage” is all fine and dandy if you’re constantly looking at the Browser Console… but who is constantly looking at the Browser Console? Certainly not me.
Instead, I whipped up a quick and dirty add-on that plays a click, like a Geiger Counter, anytime “unsafe CPOW usage” is put into the Browser Console. This has already highlighted some places where we can reduce unsafe CPOW usage in core Firefox code – particularly:
If you’re interested in helping me find more, install this add-on5, and listen for clicks. At this point, I’m only interested in unsafe CPOW usage caused by core Firefox code, so you might want to disable any other add-ons that might try to synchronously communicate with content.
If you find an “unsafe CPOW usage” that’s not already blocking this bug, please file a new one! And cc me on it! I’m mconley at mozilla dot com.
|
Air Mozilla: Martes mozilleros |
Reuni'on bi-semanal para hablar sobre el estado de Mozilla, la comunidad y sus proyectos.
|
Gregory Szorc: Lost Productivity Due to Non-Unified Repositories |
I'm currently working on annotating moz.build files with metadata that defines things like which bug component and code reviewers map to which files. It's going to enable a lot of awesomeness.
As part of this project, I'm implementing a new moz.build processing mode. Instead of reading moz.build files by traversing DIRS variables from previously-executed moz.build files, we're evaluating moz.build files according to filesystem topology. This has uncovered a few cases where a moz.build file errors because of assumptions that no longer hold. For example, for directories that are only active on Windows, the moz.build file might assume that if Windows is always true.
One such problem was with gfx/angle/srx/libGLESv2/moz.build. This file contained code similar to the following:
if CONFIG['IS_WINDOWS']:
SOURCES += ['foo.cpp']
...
SOURCES['foo.cpp'].flags += ['-DBAR']
This always ran without issue because this moz.build was only included if building for Windows. This assumption is of course invalid when in filesystem traversal mode.
Anyway, as part of updating this trouble file, I lost maybe an hour of productivity. Here's how.
The top of the trouble moz.build file has a comment:
# Please note this file is autogenerated from generate_mozbuild.py,
# so do not modify it directly
OK. So, I need to modify generate_mozbuild.py. First thing's first: I need to locate it:
$ hg locate generate_mozbuild.py
gfx/skia/generate_mozbuild.py
So I load up this file. I see a main(). I run the script in my shell and get an error. Weird. I look around gfx/skia and see a README_MOZILLA file. I open it. README_MOZILLA contains some instructions. They aren't very good. I hop in #gfx on IRC and ask around. They tell me to do a Subversion clone of Skia and to check out the commit referenced in README_MOZILLA. There is no repo URL in README_MOZILLA. I search Google. I find a Git URL. I notice that README_MOZILLA contains a SHA-1 commit, not a Subversion integer revision. I figure the Git repo is what was meant. I clone the Git repo. I attempt to run the generation script referenced by README_MOZILLA. It fails. I ask again in #gfx. They are baffled at first. I dig around the source code. I see a reference in Skia's upstream code to a path that doesn't exist. I tell the #gfx people. They tell me sub-repos are likly involved and to use gclient to clone the repo. I search for the proper Skia source code docs and type the necessary gclient commands. (Fortunately I've used gclient before, so this wasn't completely alien to me.)
I get the Skia clone in the proper state. I run the generation script and all works. But I don't see it writing the trouble moz.build file I set out to fix. I set some breakpoints. I run the code again. I'm baffled.
Suddenly it hits me: I've been poking around with gfx/skia which is separate from gfx/angle! I look around gfx/angle and see a README.mozilla file. I open it. It reveals the existence of the Git repo https://github.com/mozilla/angle. I open GitHub in my browser. I see a generate_mozbuild.py script.
I now realize there are multiple files named generate_mozbuild.py. Unfortunately, the one I care about - the ANGLE one - is not checked into mozilla-central. So, my search for it with hg files did not reveal its existence. Between me trying to get the Skia code cloned and generating moz.build files, I probably lost an hour of work. All because a file with a similar name wasn't checked into mozilla-central!
I assumed that the single generate_mozbuild.py I found under source control was the only file of that name and that it must be the file I was interested in.
Maybe I should have known to look at gfx/angle/README.mozilla first. Maybe I should have known that gfx/angle and gfx/skia are completely independent.
But I didn't. My ignorance cost me.
Had the contents of the separate ANGLE repository been checked into mozilla-central, I would have seen the multiple generate_mozbuild.py files and I would likely have found the correct one immediately. But they weren't and I lost an hour of my time.
And I'm not done. Now I have to figure out how the separate ANGLE repo integrates with mozilla-central. I'll have to figure out how to submit the patch I still need to write. The GitHub description of this repo says Talk to vlad, jgilbert, or kamidphish for more info. So now I have to bother them before I can submit my patch. Maybe I'll just submit a pull request and see what happens.
I'm convinced I wouldn't have encountered this problem if a monolithic repository were used. I would have found the separate generate_mozbuild.py file immediately. And, the change process would likely have been known to me since all the code was in a repository I already knew how to submit patches from.
Separate repos are just lots of pain. You can bet I'll link to this post when people propose splitting up mozilla-central into multiple repositories.
http://gregoryszorc.com/blog/2015/02/17/lost-productivity-due-to-non-unified-repositories
|
Soledad Penades: How to organise a WebGL event |
I got asked this:
Going to organize a series of open, and free, events covering WebGL / Web API […]
We ended up opting for an educational workshop format. Knowing you have experience with WebGL, I’d like to ask you if you woudl support us in setting up the materials […]
In the interest of helping more people that might be wanting to start a WebGL group in their town, I’m posting the answer I gave them:
I think you’re putting too much faith on me
I first learnt maths and then OpenGL and then WebGL. I can’t possibly give you a step by step tutorial that mimics my learning process.
If you have no prior experience with WebGL, I suggest you either look for a (somewhat) local speaker and try to get them to give an introductory talk. Probably people that attend the event will be interested in WebGL already or will get interested after the talk.
Then just get someone from the audience excited about WebGL and have them give the next talk
If you can’t find any speaker, then you’ll need to become one, and for that you’ll need to document yourself. I can’t write a curriculum for you, as it will take way more time than I currently have. WebGL implies many things, from understanding JavaScript to understanding 3D geometry and maths, to how to set the whole system up and running on a browser.
Or can start by learning to use a library such as three.js and once you become acquainted with its fundamentals, start digging into “pure WebGL” if you want, for example writing your own custom shaders.
Or another thing you could do is get together a bunch of people interested in WebGL and try to follow along the tutorials on WebGL or the examples on three.js. So people can discuss aloud what they understand and what they don’t, and help and learn from each other.
I hope this helps you find your way around this incredibly vast subject! Good luck and have fun!
Now you know how to do this. Go and organise events! EASY!
It’s actually not easy.
http://soledadpenades.com/2015/02/17/how-to-organise-a-webgl-event/
|
Gervase Markham: Alice and Bob Are Weird |
Suppose Alice and Bob live in a country with 50 states. Alice is currently in state a and Bob is currently in state b. They can communicate with one another and Alice wants to test if she is currently in the same state as Bob. If they are in the same state, Alice should learn that fact and otherwise she should learn nothing else about Bob’s location. Bob should learn nothing about Alice’s location.
They agree on the following scheme:
- They fix a group G of prime order p and generator g of G
- …
Cryptographic problems. Gotta love ‘em.
http://feedproxy.google.com/~r/HackingForChrist/~3/PiMWxSO0374/
|
Wil Clouser: Marketplace and Payments Systems Diagrams |
A couple years ago Krupa filled up a whiteboard with boxes and arrows, diagramming what the AMO systems looked like. There was recently interest in reviving that diagram and seeing what the Marketplace systems would look like in the same style so I sat down and drew the diagrams below, one for the Marketplace and one for Payments.
Marketplace:
Payments:
Honestly, I appreciate the view, but I wince at first glance because of all the duplication. It's supposed to be "services from the perspective of a single service." Meaning, if the box is red, anything connected to it is what that box talks to. Since the webheads talk to nearly everything it made sense to put them in the middle, and the dotted lines simply connect duplicate services. I'm unsure whether that's intuitive though, or if it would be easier to understand if I simply had a single node for each service and drew lines all over the diagram. I might try that next time, unless someone gives me a different idea. :)
Lastly, this is the diagram that came out first when I was trying to draw the two above. It breaks the Marketplace down into layers which I like because we emphasize being API driven frequently, but I'm not sure the significant vertical alignment is clear unless you're already familiar with the project. I think finding a way to use color here would be helpful - maybe as a background for each "column."
Or maybe I'm being too hard on the diagrams. What would you change? Are there other areas you'd like to see drawn out or maybe this same area but through a different lens?
http://micropipes.com/blog//2015/02/17/marketplace-architecture-diagrams/
|
Chris McDonald: Owning Your Stack |
A few months back I wrote about reinventing wheels. Going down that course has been interesting and I hope to continue reinventing parts of the personal cloud stack. Personal cloud meaning taking all of the services you have hosted elsewhere and pulling them in. This feeds into the IndieWeb movement as well.
A couple years ago, I deployed my first collocated server with my friends. I got a pretty monstrous setup compared to my needs, but I figured it’d pay for itself over time and it has. One side effect of having all this space was that I could let my friends also have slices of my server. It was nice sharing those extra resources. Unfortunately, by hosting my friend’s slices of my server, it meant doing anything to the root system or how the system was organized was a bit tedious or even off limits.
In owning my own services, I want to restructure my server. Also I want to have interesting routing between containers and keep all the containers down to the single process ideal. In order to move to this world I’ve had to ask my friends to give up their spots on my server. Everyone was really great about this thanking me for hosting for this long and such. I was worried people would complain and I’d have to be more forceful, but instead things were wonderful.
The next step I want to take after deploying my personal cloud, will be to start one by one replacing pieces with my own custom code. The obvious first one will be the SMTP server since I’ve already started implementing one in rust. After that it may be something like my blog, or redis or a number of other parts of the cloud. The eventual goal being that I’ve implemented a fair portion of all cloud services and I can better understand them. I wont be restricting myself to any one language. I will be pushing for a container per process with linking between containers to share services.
Overall, I hope to learn a bunch and have some fun in the process. I recently picked up the domain http://ownstack.club and hope to have something up on it in the near future!
|
Mark C^ot'e: Pulse update |
After languishing for a few years, Pulse got a burst of interest and development in 2014. Since I first heard of it, I’ve found the idea of a central message bus for the goings-on in Mozilla’s various systems rather intruiging, and I’m excited to have been able to grow it over the last year.
Pulse falls into that class of problem that is a result of, to borrow from a past Mozilla leader, our tendency to make our lives difficult, that is, to work in the open. Using RabbitMQ as a generic event stream is nothing special; Mozilla’s use of it as an open system is, I believe, completely unique.
Adapting a system intended for private networks into a public service always results in fascinating problems. Pulse has a decent permission-control system, but it’s not designed for self service. It is also very trusting of its users, who can easily overwhelm the system by just subscribing to streams and never consuming the messages.
The solution to both these problems was to design a management application: PulseGuardian. Via Persona, it handles account management, and it comes with a service that monitors Pulse’s queues. Since we presume users are not malicious, it sends a friendly warning when it notices a queue growing too large, but if ignored it will eventually kill the queue to save the system.
If you build it, they will come, or so says some movie I’ve never seen, but in this case it appears to be true. TaskCluster has moved whole-hog over to Pulse for its messaging needs, and the devs wrote a really nice web app for inspecting live messages. MozReview is using it for code-review bots and autolanding commits. Autophone is exploring its use for providing Try support to non-BuildBot-based testing frameworks.
Another step for Pulse beyond the prototype phase is a proper library. The existing mozillapulse Python library works decently, aside from some annoying problems, but it suffers from a lack of extensibility, and, I’m beginning to believe, should be based directly on a lower-level amqp or RabbitMQ-specific Python package and not the strange, overly generic kombu messaging library, in part because of the apparent lack of confirm channels in kombu. We’re looking into taking ideas from TaskCluster’s Pulse usage in bug 1133602.
Recently I presented the State of Pulse to the A-Team. I should do that as a general brownbag at some point, but, until then, you can look at the slides.
|
Mike Conley: The Joy of Coding (Episode 1) |
Here’s the first episode! I streamed it last Wednesday, and it was mostly concerned with bug 1090439, which is about making the print dialog and progress calls from the child process asynchronous.
Here are the notes for that bug. I still haven’t closed it yet, so perhaps I’ll keep pressing on this next Wednesday when I stream Episode 2. We’ll see!
A note that I did struggle with some resolution issues in this episode. I’m working with Richard Milewski from the Air Mozilla team to make this better for the next episode. Sorry about that!
http://mikeconley.ca/blog/2015/02/16/the-joy-of-coding-episode-1/
|
Air Mozilla: Mozilla Weekly Project Meeting |
The Monday Project Meeting
https://air.mozilla.org/mozilla-weekly-project-meeting-20150216/
|
Jared Wein: Starting of my new mentoring program |
Today starts the first day of the mentoring program that I announced in my previous blog post.
In good news, I was overwhelmed by the number of responses I received to the blog post. Within three days, 57 people sent me an email requesting to be a part of the program. This tells me there is a strong need for more guided programs like this. On the downside, it was very hard to select only four people from the group.
In the end, I ended up selecting five people to partake in this. They are from all over the world: India (2); Germany; and USA (2).
I have assigned the first bugs and work should proceed this week on getting a build working and finding their way through the Firefox developer ecosystem.
https://msujaws.wordpress.com/2015/02/16/starting-of-my-new-mentoring-program/
|
Mark Surman: Participation, permission and momentum |
Don’t wait for permission. If you have an idea that excites you, a thing you want to prototype, a skill you proudly want to share, an annoying bug you want to fix, a conversation you want to convene: don’t wait for someone else to say yes. Just do it!
This is useful (and common) advice for pretty much any endeavor. But, for Mozilla and Mozillians, it’s critical. Especially right now.
We’ve committed to building a more radical approach to participation over the next three years. And, more specifically, we ultimately want to get to a place where we have more Mozilla activities happening than the centralized parts of the org can track, let alone control.
How do we do this? One big step is reinvigorating Mozilla’s overall architecture of participation: the ways we help people connect, collaborate and get shit done. This is both important and urgent. However, as we work on this, there is something even more urgent: keeping up the momentum that comes from simply taking action and building great stuff. We need to maintain momentum and reinvigorate our architecture of participation in tandem in order to succeed. And I worry a little that recent discussions of participation have focused a little too heavily on the architecture part so far.
The good news: Mozillians have a deep history of having a good idea and just running with it. With the best ideas, others start to pitch in time and resources. And momentum builds.
A famous example of this is the Firefox 1.0 New York times ad in 2004. A group of volunteers and supporters had the idea of celebrating the launch of Firefox in a big way. They came up with a concept and started running with it. As a momentum built, Mozilla Foundation staff came in to help. The result was the the first high profile crowd-funded product launch in history — and a people-powered kickoff to Firefox’s dramatic rise in popularity.
This kind of thing still happens all the time today. A modest example from the last few weeks: the Mozilla Bangladesh community’s participation at BASIS. Mozilla volunteers arranged to get a booth and a four hour time slot for free at this huge local tech event, something other companies paid $10,000 to get. They then organized an ambitious program that covered everything from Firefox OS demos to contributing to SuMo to teaching web literacy to getting involved in MDN, QA and web app development — they covered a broad swatch of top priority Mozilla topics and goals. Mozilla staff helped and encouraged remotely. But this really was driven locally and from the ground up.
Separated by 10 years and operating at very different scale, these two examples have a number of things in common: the ideas and activities were independently initiated but still tied back to core Mozilla priorities; initial resources needed to get the idea moving were gathered by the people who would make it happen (i.e. initial donations or free space at a conference); staff from the central Mozilla organization came in later in the process and played a supporting role. In each case, decentralized action led to activities and outcomes that drove things forward on Mozilla’s overall goals of the time (e.g. Firefox adoption, Webmaker growth, SuMo volunteer recruitment).
This same pattern has happened thousands of times over, with bug fixes, documentation, original ideas that make it into core products and, of course, with ads and events. While there are many other ways that people participate, independent and decentralized action where people ‘just do something’ is an important and real part of how Mozilla works.
As we figure out how to move forward with our 2015+ participation plan, I want to highlight this ‘don’t wait for permission’ aspect of Mozilla. Two things seem particularly important to focus on right now:
First: strengthening decentralized leadership at Mozilla. For me, this is critical if we’re serious about radical participation. It’s so core to who we are and how we win. To make progress here, we need to admit that we’re not as good at decentralized leadership today as we want or need to be. And then we need to have an an honest discussion about the goals that Mozilla has in the current era and how to build up decentralized leadership in a way helps move those goals forward. This is a key piece of ‘reinvigorating Mozilla’s architecture of participation’.
A second, and more urgent, topic: maintaining momentum across the Mozilla community. It’s critical that Mozillians continue act on their ideas and take initiative even as we work through these broader questions of participation. I’ve had a couple of conversations recently that went something like ‘it feels like we need to wait on a ‘final plan’ re: participation before going ahead with an idea we have’. I’m not sure if I was reading those conversations right or if this is a widespread feeling. If it is, we’re in deep trouble. We won’t get to more radical participation simply by bringing in new ideas from other orgs and redesigning how we work. In fact, the more important ingredient is people taking action at the grassroots — running with an idea, prototyping something, sharing a skill, fixing an annoying bug, convening a conversation. It’s this sort of action that fuels momentum both in our community and with our products.
For me, focusing on both of these themes simultaneously — keeping momentum and reinvigorating our architecture of participation — is critical. If we focus only on momentum, we may get incrementally better at participation, but we won’t have the breakthroughs we need. If we just focus on new approaches and architectures for participation, we risk stalling or losing the faith or getting distracted. However, if we can do both at once, we have the chance to unlock something really powerful over the next three years — a new era of radical participation at Mozilla.
The draft participation plan we’ve developed for the next three years is designed with this in mind. It includes a new Community Development Team to help us keep momentum, with a particular focus on supporting Mozilla community members around the world who are taking action right now. And we are setting up a Participation Task Force (we need a better name for this!) to get new ideas and systems in place that help us improve the overall architecture of participation at Mozilla. These efforts are just a few weeks old. As they build steam and people get involved, I believe they have the potential to take us where we want to go.
Of course, the teams behind our participation plan are a just a small part of the story: they are a support for staff and volunteers across Mozilla who want to get better at participation. The actual fuel of participation will come from all of us running with our ideas and taking action. This is the core point of my post: moving towards a more radical approach to participation is something each of us must play a role in. Playing that role doesn’t flow from plans or instructions from our participation support teams. It flows from rolling up our sleeves to passionately pursue good ideas with the people around us. That’s something all of us need to do right now if we believe that radical participation is an important part of Mozilla’s future.
https://commonspace.wordpress.com/2015/02/15/participation-permission-and-momentum/
|
Christian Heilmann: Flipboard and the “mobile web” dream… |
According to the luminaries of the web design world, the “mobile web” doesn’t exist. Stephen Hay said it, Smashing Magazine said so and Jeremy Keith amongst many others.
Except, it does. Not as a technical reality, but as a dream of marketing and overly excited managers who believe in magical powers of their engineers. And it is nothing new. We’ve been there before, and we probably will get there again. Every few years a new form factor or technology comes out that promises a web that is catering perfectly to a very niche need whilst being open and available to all. Or – in other words – water that is almost, but not totally wet.
Last week Flipboard engineering released the Kraken with their “60 fps on the mobile web” post, explaining how they managed to give the new “web version” of Flipboard a buttery smooth 60 frames per second on mobile by forfeiting the DOM and rendering the whole thing in Canvas. The general outrage was that it was read as a call to give up on the DOM and use react.js and Canvas instead.
Not surprisingly, this sparked a lot of discussion and annoyance toward them. But let’s step back a bit: first of all, it is a good thing when engineering teams publish their findings and tell us why they made some decisions. It can be a great learning resource and is a courageous thing to do. In a world where people spend most of their time dismembering technical posts on hacker news putting yourself out there means you also need to deal with a lot of polarised feedback. You need to learn fast how to deal with trolls and people using these systems to grandstand. So, thanks are in order – thank you, Flipboard. The post is detailed, it explains what they tried to do and how they achieved it.
The usefulness of such a resource starts getting questionable when hype kicks in and people take it as gospel. Flipboard did not claim that what they do is the perfect way to achieve happiness on mobile. Instead they are very open about their intentions:
In the pursuit of 60fps we sometimes resort to extreme measures. Flipboard for mobile web is a case study in pushing the browser to its limits. While this approach may not be suitable for all applications, for us it’s enabled a level of interaction and performance that rivals native apps.
Right now, mobile is still hot. HTML5 is still hot. A company pushing the boundaries of both is hot. That’s why it is good value for a tech company to write articles like that. And I am 100% sure the Flipboard engineers have the heart in the right place and rightfully are proud of what they have achieved.
That said, the title is terrible as it promises a simple answer to a huge problem. Or, on reflection, not a problem, but a massive misunderstanding.
What this post told me most of all is that it isn’t solving an issue of the web. It is about simulating a native interface for a mobile touch device at 60 fps using web technologies. It’s aim is to run smoothly on the currently hot device that the most affluent people use – let’s say the iPhone 6. They are not beating around the bush about this at all:
Now we’re coming full circle and bringing Flipboard to the web. Much of what we do at Flipboard has value independent of what device it’s consumed on: curating the best stories from all the topics, sources, and people that you care about most. Bringing our service to the web was always a logical extension.
There’s a massive flaw in this: it tries to bring value independent of what device it is consumed on and then it applies assumptions and concepts that are only beneficial to a mobile, touch-enabled device.
This is a porting exercise. This is bringing something to the web. It is not creating a web product. That would be reaching as many people as possible, and making your content available independent of hardware, ability and environment. You can not “go to web”. The web is not another form factor when your starting point is a very restricted environment. That’s how we got text-only versions of Flash movies and “accessible versions” of DHTML monstrosities. Using web technology means you start with the assumption that you have no control over the way your content is consumed. And that’s as far removed as it can from what Flipboard said:
Flipboard launched during the dawn of the smartphone and tablet as a mobile-first experience, allowing us to rethink content layout principles from the web for a more elegant user experience on a variety of touchscreen form factors.
And this is why calling this a web experience is ill-advised from the get-go. As Faruk Ates put it:
…what Flipboard unleashed onto the world a “Web” version is akin to calling a collection of tires, AA batteries and spare car parts a Tesla.
This is not about the technical implementation. The flaw is in the idea of turning a native app that was specifially designed for a certain form factor into a “web version”. The journey explained is full of assumptions.
The first one is the big 60. All our web technology efforts need to match the 60 fps threshold or they are useless, right? Well, looking at my Nexus 5 device with Android Lollipop and anything I could do to be state-of-the-art I can safely say that not a single app works consistently smoothly at 60 fps or doesn’t stutter from time to time. So, I guess, I have no apps.
Of course, we need goals to aspire to and some things to measure against. But defining something like 60fps as a baseline is pretty naive considering the fragmentation of hardware and the amount of abstraction layers an HTML5 app has to go through. Maybe considering less greedy interaction models might be a way forward?
Which brings me to the second assumption: endless scrolling is what the web is about. And from there, the article tries to make that work. True, a lot of solutions have endless scrolling. Also true, many a time that is more annoying than a pagination would have been.
What Flipboard did here is to build a native-feel solution in an environment that has no native paradigms. There are no form-factor standards on the web. They change constantly. The parallax scrolling page today is the multi-level DHTML drop-down of tomorrow.
It is a daring and seemingly clever solution to go for canvas to reach good performance in an endless scrolling interface. But that’s all it is – a currently clever solution with a very short shelf-life. As Rachel Nabors put it:
Re: recreating the DOM in canvas and accessibility: we will look back on this as a hack. Browsers will catch up, will render the DOM faster.
When working on Firefox OS and low-end devices, the main issue just a few months ago was that canvas was too slow and people used the DOM instead and complained that it is the wrong API for games. The push was towards canvas to become hardware accelerated or – even better – mobile browsers to support WebGL. Now we have this and many a DOM solution using all kind of 3D transform tricks in CSS to force hardware accelerated layers look silly. Much like this might look silly very soon.
The honest approach to this would be to give the article the title “How we created endless scrolling at 60 fps on high-end mobile devices by replacing the DOM with Canvas”. But that’s not as quotable and it doesn’t make you sound like a trailblazer solving a “real and very common” problem.
Flipboard already admits that in terms of accessibility, this is a horrible solution. Screenreader availability aside, my warning bells went off when I saw elements with not only fixed positions on the screen but also fixed dimensions. And when you use a tool that supports text but means you need to calculate line breaks, I’d get a queasy feeling in my stomach. There goes resizing the font. There goes copying and pasting. There goes translating a text. All things the web is great at. And it is nothing new.
Every single time we replaced text with graphics to gain more control we had to re-invent these basic features of a text-based web. Remember image replacement techniques of headlines before we had web fonts? Remember how Flash had to bend over backwards to seed the browser history and to make text highlight-able? Remember how it was impossible on mobile devices to copy and paste at all?
When reading the section of the post about accessibility I get flashbacks to horrible times:
This area needs further exploration. Using fallback content (the canvas DOM sub-tree) should allow screen readers such as VoiceOver to interact with the content. We’ve seen mixed results with the devices we’ve tested. Additionally there is a standard for focus management that is not supported by browsers yet.One approach that was raised by Bespin in 2009 is to keep a parallel DOM in sync with the elements rendered in canvas. We are continuing to investigate the right approach to accessibility.
Wait a second. Re-read this, please, and tell me if I am crazy when I think this sounds like a lot of duct-tape around a leaking faucet.
We have a perfectly accessible way of achieving all of this: we call it HTML and we have the DOM and the accessibility API. That way we’d have a perfectly working web site that gets found, indexed, is accessible to a lot of people. We can then convert into a fast performing canvas solution on mobile devices that are touch-enabled. We can test for that – web technology is good at that. Think about it: a data source that comes with lots of accessibility benefits and already has an API to read it in part? Sign me up.
Instead we consider adding a lot of HTML content inside the canvas element as a fallback and hope browsers and assistive technology will do something with that.
Content inside canvas becomes interesting when canvas isn’t supported. Today, that’s an almost non-existent use case. Browsers support canvas. It is a blank, stateless placeholder in the page that we paint on and wipe. It is an etch-a-sketch in the page. It isn’t even vector based – it is a dumb collection of pixels. That’s why canvas is fast – the Flipboard article does a good job explaining that.
Canvas is to HTML5 what DIV and SPAN are to HTML4 - it has no semantic meaning. It is a placeholder for generated, visual content. Not text, not interactive elements. When canvas came to be, the first comments were that it is the new applet. And that is still quite a sensible way of describing it from a markup/semantic meaning angle. It is as much a black box in the page as Flash was to the rest of the markup.
The problem with Flipboard’s solution to the mobile performance issue is that it wants to use canvas because of its stateless and high-performance nature and get all the benefits of HTML and the DOM at the same time. This is asking too much.
We could, however, get quite a long way by creating our canvas content from HTML that is in the document. And that is what it means to build a web product – you build a sensible HTML solution first, and then use CSS and JavaScript to enhance it. That way you don’t need to worry about covering the basics after you fine-tuned the final product. That approach will always result in disappointing fallbacks that are hardly ever maintained.
The whole goal of this exercise was to match native performance by using web technology and applying ideas of native environments. And this is a thing we should be aware of. The mobile web.
The issue is that according to this post and many others of the same ilk, the mobile web exists. The mobile web is not a technical thing – it is a misconception and one that is hard to match. Companies nowadays start with a native experience. This is where the short-term gain is. This is where the short-term high user numbers lie. This is the beautiful technology – the shiny devices, the backing from OS vendors and the exciting interaction models that come with the OS. It feels good, it feels that there is something to work with.
Then these people hear about the benefits of web technologies: cross-platform support, lower cost of engineering as you don’t need to pay experts of red-hot new technologies, re-use across different form factors and so on. A lot of times this happens when the honeymoon period of the native solution is over and there is new growth to be unearthed.
Then, they want both. Hence, “the mobile web”.
We have two issues to battle with this: a technical problem and an image problem.
Let’s talk technical first: matching the performance of a native app with a web app is a game the web can currently not win. At least not if all you count as performance is its fps speed and how well it integrates with the OS. The reason is that the cards are stacked against us. Unless the browser becomes the most important thing in a mobile OS, we will always have a hacky experience.
To the OS vendor, the browser is a necessary thing to offer – another app much like the calculator or the phone app. From a marketing and monetary point of view, having people build exclusively for your platform with your tools and in your languages is a win-win. You have a captive audience and you can show their numbers in huge figures during your keynotes to your stakeholders. Making the browser amazing means you have to share.
Add to this the ridiculous browser fragmentation and the amount of zombie browsers on older systems that will never get an update again and you will find that matching the newest and coolest of the native offering is really hard.
The image problem is that the web seems stale. Our market thrives on hype and short term gains. All our messaging about the web is praising its longevity. What you do now means you will benefit in years to come, even if it means some extra work. Your products will be easy to maintain for years to come. Future technology will already support what you do now and it will be easy to extend if you use progressive enhancement. This is our messaging, and it is great messaging.
Except when all you care about is the next month’s user and download numbers and how many people posted selfies and sent stickers to each other that you sold them. Then this message is just noise and sounds like arrogant “in my days” speeches.
If we love the web and want it to work out, we need to pick our battles. And the real battle lies with operating systems not having a browser we can rely on. And with lack of support of very basic features we need to give an app experience across browsers and platforms. And with a lack of standards that really get to fruition and are implemented instead of being replaced by a library that is open source, but never leaves beta.
The mobile web is real – and it isn’t. It is a dream of people who don’t get the nature of the web trying to harvest its benefits. And right now, these people get all the VC money and get the tech press excited as they promise something new. The hype as it is now is not sustainable. It killed these people once in the dotcom boom and will again – very soon.
We can stomp our foot about that and get angry and we can repeat tiring old messages. Or we can bide our time and fix what is broken and keeps us from performing the way we want to. Let those who need the quick short-term win pretend they found the solution. Our time can be used differently. The amount of devices, form factors and user needs is not decreasing any time soon. The web can cover all of them. Let’s make that happen once the fever dream of the one true app form factor is over. Much like there is not one mode of transport to cover all needs, there is no such thing as a perfect app or interaction model.
http://christianheilmann.com/2015/02/15/flipboard-and-the-mobile-web-dream/
|
Cameron Kaiser: IonPower now entering low Earth orbit |
function ok(){print("ok");}function ok3(){ok(ok(ok()));}var i=0;for(i=0;i<12;i++){ok3();}
That's an awful lot of affirmation right there. Once I'm confident I can scale it up a bit more, then we'll try to get the test suite to pass.
What does IonPower bring to TenFourFox, besides of course full Ion JIT support for the first time? Well, the next main thing it does is to pay back our substantial accrued technical debt. PPCBC, the current Baseline-only implementation, is still at its core using the same code generator and assumptions about macroassembler structure from JaegerMonkey and, ultimately, TenFourFox 10.x; I got PPCBC working by gluing the new instruction generator to the old one and writing just enough of the new macroassembler to enable it to build and generate code.
JaegerMonkey was much friendlier to us because our implementation was always generating (from the browser's view) ABI-compliant code; JavaScript frames existed on a separate interpreter stack, so we could be assured that the C stack was sane. Both major PowerPC ABIs (PowerOpen, which OS X and AIX use, and SysV, which Linux, *BSD, et al. use) have very specific requirements for how stack frames are formatted, but by TenFourFox 17 I had all the edge cases worked out and we knew that the stack would always be in a compliant state at any crossing from generated code back to the browser or OS. Ben Stuhl had done some hard work on branch and call stanza optimization and this mostly "just worked" because we had full control to that level.
Ion (and Baseline, its simpleton sibling) destroyed all that. Now, script frames are built on the C stack instead, and Ion has its own stack frame format which it always expects to be on top, meaning when you enter Ion generated code you can't directly return to ABI-compliant code without some sort of thunk and vice versa. This frame has a descriptor and a return address, which is tricky on PowerPC because we don't store return addresses on the stack like x86, the link register we do have (the register storing where a subroutine call should return to) is not a general purpose register and has specialized means for controlling it -- part of the general class of PowerPC SPRs, or special purpose registers -- and the program counter (the internal register storing the location of the current instruction) is not directly accessible in any fashion. Compare this with MIPS, where the link register is a GPR ($ra), and ARM, where both the LR and PC are. Those CPUs can just sling them to and from the stack at will.
That return address is problematic in another respect. We use constructs called branch stanzas in the PowerPC port, because the PPC branch instructions have a limited signed displacement of (at most, for b) 26 bits, and branches may exceed that with the size of scripts these days; these stanzas are padded with nop instructions so that we have something to patch with long calls (usually lis ori mtctr bctr) later. In JagerMonkey (and PPCBC), if we were making a subroutine call and the call was "short," the bl instruction that performed it was at the top of the branch stanza with some trailing nops; JaegerMonkey didn't care how we managed the return as long as we did. Because we had multiple branch variants for G3/G4 and G5, the LR which bl set could be any number of instructions after the branch within the stanza, but it didn't matter because the code would continue regardless. To Ion, though, it matters: it expects that return address on the stack to always correlate to where a translated JSOP (JavaScript interpreter opcode) begins -- no falling between the cracks.
IonPower deals with the problem in two ways. First, we now use a unified stanza for all architectures, so it always looks the same and is predictable, and short branches are now at the end of the stanza so that we always return to the next JSOP. Second, we don't actually use the link register for calling generated code in most cases. In both PowerPC ABIs, because LR is only set when it gets to the callee (the routine being called) the callee is expected to save it in its function prologue, but we don't have a prologue for Baseline code. PPCBC gets around this by using the link register within Baseline code only; for calls out to other generated code it would clobber the link register with a bl .+4 to get the PC, compute an offset and store that as a return address. However, that offset was sometimes wrong (see above), requiring hacks in the Ion core to do secondary verification. Instead, since we know the address of the instruction for the trailing JSOP at link time, we just generate code to push a 32-bit literal and we patch those push instructions when we link to memory to the right location. This executes faster, too, because we don't have all that mucking about with SPR operations. We only use the link register for toggled calls (because we control the code it calls, so we can capture LR there) and for bailout tables, and of course for the thunk code that calls ABI-compliant library routines.
This means that a whole class of bugs, like branching, repatching and stack frame glitches, just disappear in IonPower, whereas with PPCBC there seemed to be no good way to get it to work with the much more sophisticated Ion JIT and its expectations on branching and patching. For that reason, I simply concentrated on optimizing PPCBC as much as possible with high-performance PowerPC-specific parallel type guards and arithmetic routines in Baseline inline caches, and that's what you're using now.
IonPower's other big step forward is improved debugging abilities, and chief amongst them is no compiler warnings -- at all. Yep. No warnings, at least not from our headers, so that subtle bugs that the compiler might warn about can now be detected. We also have a better code generation display that's easier to visually parse, and annoying pitfalls in PowerPC instructions where our typical temporary register r0 does something completely different than other registers now assert at code generation time, making it easier to find these bugs during codegen instead of labouriously going instruction by instruction through the debugger at runtime.
Incidentally, this brought up an interesting discussion -- how does, say, MIPS deal with the return address problem, since it has an LR but no GPR PC? The MIPS Ion backend, for lack of a better word, cheats. MIPS has a single instruction branch delay slot, i.e., the instruction following any branch is (typically) executed before the branch actually takes place. If this sounds screwy, you're right; ARM and PowerPC don't have them, but some other RISC designs like MIPS, SuperH and SPARC still do as a historical holdover (in older RISC implementations, the delay slot was present to allow the processor enough time to fetch the branch target, and it remains for compatibility). With that in mind, and the knowledge that $ra is the MIPS link register, what do you think this does?
addiu $sp,$sp,-8 ; subtract 8 from the current stack pointer,
; reserving two words on the stack
jalr $a0 ; jump to address in register $a0 and set $ra
sw $ra, 0($sp) ; (DELAY SLOT) store $ra to the top of the stack
What's the value of $ra in the delay slot? This isn't well-documented apparently, but it's actually already set to the correct return address before the branch actually takes place, so MIPS can save the right address to the stack right here. (Thanks to Kyle Isom, who confirmed this on his own MIPS system.) It must be relatively standard between implementations, but I'd never seen a trick like that before. I guess there has to be at least some advantage to still having branch delay slots in this day and age.
One final note: even though necessarily I had to write some of it for purposes of compilation, please note that there will be no asm.js for PowerPC. Almost all the existing asm.js code out there assumes little endian byte ordering, meaning it will either not run or worse run incorrectly on our big endian machines. It's just not worth the headache, so they will run in the usual JIT.
On the stable branch side, 31.5 will be going to build next week. Dan DeVoto commented that TenFourFox does not colour manage untagged images (unless you force it to). I'd argue this is correct behaviour, but I can see where it would be unexpected, and while I don't mind changing the default I really need to do more testing on it. This might be the standard setting for 31.6, however. Other than the usual ESR fixes there are no major changes in 31.5 because I'm spending most of my time (that my Master's degree isn't soaking up) on IonPower -- I'm still hoping we can get it in for 38 because I really do believe it will be a major leap forward for our vintage Power Macs.
http://tenfourfox.blogspot.com/2015/02/ionpower-now-entering-low-earth-orbit.html
|
Rail Aliiev: Funsize hacking |
The idea of using a service which can generate partial updates for Firefox has been around for years. We actually used to have a server called Prometheus that was responsible for generating updates for nightly builds and the generation was done as a separate process from actual builds.
Scaling that solution wasn't easy and we switched to build-time update generation. Generating updates as a part of builds helped with load distribution, but lacked of flexibility: there is no easy way to generate updates after the build, because the update generation process is directly tied to the build or repack process.
Funsize willl solve the problems listed above: to distribute load and to be flexible.
Last year Anhad started and Mihai continued working on this project. They have done a great job and created a solution that can easily be scaled.
Funsize is split into several pieces:
One of the biggest gains of Funsize is that it uses a global cache to speed up partial generation. For example, after we build an en-US Windows build, we ask Funsize to generate a partial. Then a swarm of L10N repacks (almost a hundred of them per platform) tries to do a similar job. Every single one asks for a partial update. All L10N builds have something in common, and xul.dll is one of the biggest files. Since the files are identical there is no reason to not reuse the previously generated binary patch for that file. Repeat 100 times for multiple files. PROFIT!
The first prototype of Funsize lives at github. If you are interested in hacking, read the docs on how to set up your developer environment. If you don't have an AWS account, it will use a local cache.
Note: this prototype may be redesigned and switch to using TaskCluster. Taskcluster is going to simplify the initial design and reduce dependency on always online infrastructure.
|
Ben Kelly: A Very Special Valentines Day Build |
Last week we introduced some custom Firefox builds that include our work-in-progress on Service Workers. The goal of these builds is to enable wider testing of our implementation as it continues to progress.
These builds have been updated today, February 14:
This week’s build provides a number of improvements:
Also, some patches that were included in last week’s build have landed in the tree for Nightly:
As always, please let us know if you have any questions or run into any problems. Thank you for your assistance in testing this new feature!
http://blog.wanderview.com/blog/2015/02/14/a-very-special-valentines-day-build/
|
Nick Alexander: Smoother Landings: How to update and test Fennec feature build flags |
First, have you read my earlier blog post Bumpy Landings? No? Go read it now! I’ll wait.
Good, you’ve read Bumpy Landings, so you’re familiar with adding and updating Fennec build flags.
The first major point: changing build settings — your mozconfig file, the configure.in script, sundry .m4 files, application-specific configuration files like mobile/android/confvars.sh — requires re-configuration to recognize your changes. You need to run:
mach configure
Unfortunately, after re-configuration, you really need to rebuild your entire tree. The issue is that mach configure updates a variety of build settings and information (including your feature flag) and the build system does not track, at a fine-grained level, what is the minimal set of things that need to rebuilt when such settings change. Hence, you need to rebuild everything to be safe, which is termed a clobber build.
The good news is that you can avoid clobber builds in some situations. First, let’s see how to find the value of a build flag. Then we’ll see how to update a value and do a limited re-build of the impacted source code.
The build system maintains the settings you see in Makefile.in and moz.build files in $OBJDIR/config.status. The only time that config.status is written is by mach configure (which may, on occasion, be triggered by other mach commands, including mach build). So to verify that your config.status is up-to-date, you can always re-run mach configure manually.
The config.status file is just a specially formatted Python script. Open it up and you’ll see there’s no magic:
#!/Users/nalexander/Mozilla/gecko/objdir-droid/_virtualenv/bin/python # coding=utf-8 import os import types topsrcdir = '''/Users/nalexander/Mozilla/gecko''' if not os.path.isabs(topsrcdir): rel = os.path.join(os.path.dirname(__file__), topsrcdir) topsrcdir = os.path.abspath(rel) topsrcdir = os.path.normpath(topsrcdir) topobjdir = os.path.abspath(os.path.dirname(__file__)) defines = [(name[1:-1], value[1:-1]) for name, value in [ (''' ANDROID ''', ' 1 '), ... ] ] substs = [(name[1:-1], value[1:-1] if isinstance(value, types.StringTypes) else value) for name, value in [ (''' SHELL ''', r''' /bin/sh '''), ... ] __all__ = ['topobjdir', 'topsrcdir', 'defines', 'non_global_defines', 'substs'] if __name__ == '__main__': args = dict([(name, globals()[name]) for name in __all__]) from mozbuild.config_status import config_status config_status(**args)
The second major point: you can always determine what the build system thinks a build setting by extracting values from either the defines or the substs list of $OBJDIR/config.status. The substs list corresponds to the CONFIG dictionary in moz.build files. (It’s less obvious how defines works.)
I’m going to take a work-in-progress patch from Bug 1132185 as my example. I’ve applied the patch locally and pushed it to the review mercurial repository. You can view the commit or fetch it with:
hg pull https://reviewboard-hg.mozilla.org/review -r 006d3619a5da
The changeset itself is small and self-contained — exactly how we like build system changes. The patch:
There’s a weirdness here in the way that mozconfig options are interpolated into configure.in which means that setting a default value does not do what you would expect. So let’s remove the default in configure.in:
diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in @@ -3938,17 +3938,16 @@ MOZ_WEBSMS_BACKEND= MOZ_ANDROID_NEW_TABLET_UI= -MOZ_ANDROID_TAB_QUEUE= ACCESSIBILITY=1
For the purposes of testing, that last is not desirable. So let’s go into mobile/android/confvars.sh and comment out those lines:
diff --git a/mobile/android/confvars.sh b/mobile/android/confvars.sh --- a/mobile/android/confvars.sh +++ b/mobile/android/confvars.sh @@ -75,17 +75,17 @@ MOZ_WEBGL_CONFORMANT=1 # Enable the tab queue. This will go away in Bug 1132507. -MOZ_ANDROID_TAB_QUEUE=1 +# MOZ_ANDROID_TAB_QUEUE=1
Now, let’s run mach configure and check the build settings in config.status:
chocho:gecko nalexander$ ./mach configure && grep MOZ_ANDROID_TAB_QUEUE objdir-chrome/config.status 0:00.23 /usr/bin/make -f client.mk -s configure 0:01.00 Generating /Users/nalexander/Mozilla/gecko/configure using autoconf 0:01.28 cd /Users/nalexander/Mozilla/gecko/objdir-chrome 0:01.28 /Users/nalexander/Mozilla/gecko/configure 0:01.64 Adding configure options from /Users/nalexander/Mozilla/gecko/mozconfig-chrome 0:01.64 --target=arm-linux-androideabi 0:01.64 --enable-application=mobile/android 0:01.64 --with-android-ndk=/usr/local/Cellar/android-ndk/r8e-darwin-x86_64 0:01.64 --with-android-sdk=/usr/local/Cellar/android-sdk/22.3/platforms/android-21 0:01.77 loading cache ./config.cache ... (''' MOZ_ANDROID_TAB_QUEUE ''', r''' '''),
Observe that we see a match for MOZ_ANDROID_TAB_QUEUE, but there’s an empty value. This match is in the substs list — it means the variable is known, but not set. When we test for existence, we’ll look for a non-empty value.
Now let’s add it to our local mozconfig:
diff --git a/mozconfig b/mozconfig --- a/mozconfig 2015-02-13 12:29:09.000000000 -0800 +++ b/mozconfig 2015-02-13 12:29:05.000000000 -0800 @@ -8,2 +8,4 @@ mk_add_options MOZ_OBJDIR=./objdir-chrome + +mk_add_options MOZ_ANDROID_TAB_QUEUE=1
Re-run configure, and you should see the variable have a value:
chocho:gecko nalexander$ ./mach configure && grep MOZ_ANDROID_TAB_QUEUE objdir-chrome/config.status ... (''' MOZ_ANDROID_TAB_QUEUE ''', ' 1 '), (''' MOZ_ANDROID_TAB_QUEUE ''', r''' 1 '''),
(The first value is in the substs list; the second in the defines list. There’s a technical difference that I won’t get into here.)
For the purposes of this section, I’m going to assume that we’re experimenting with a new build flag that is Firefox for Android (Fennec) only. That means we expect all impacts of the new build flag to be localized to the mobile/android directory, and in turn that lets us rebuild less of the tree.
In the mobile/android directory, we’re very careful to preprocess as little as possible, and we maintain our build dependencies quite actively, which makes testing mobile/android-only changes generally straight-forward. That brings us to the third major point: you should always see your build changes after running mach build mobile/android.
You can verify by manually inspecting the following generated files in the object directory:
For example, adding and removing the MOZ_ANDROID_TAB_QUEUE=1 line in my mozconfig toggles the boolean in the following block of AppConstants.java for me:
public static final boolean MOZ_ANDROID_TAB_QUEUE = //@line 178 "/Users/nalexander/Mozilla/gecko/mobile/android/base/AppConstants.java.in" true; //@line 182 "/Users/nalexander/Mozilla/gecko/mobile/android/base/AppConstants.java.in"
The Firefox for Android team is always making things better for contributors — including shining light on the dark corners of the build system. Get involved with Firefox for Android or help build and test Firefox for iOS.
Discussion is best conducted on the mobile-firefox-dev mailing list and I’m nalexander on irc.mozilla.org and @ncalexander on Twitter.
http://www.ncalexander.net/blog/2015/02/13/how-to-update-and-test-fennec-feature-build-flags/
|
Air Mozilla: Webmaker Demos February 13 2015 |
Webmaker Demos February 13 2015
|