2014-03-28

simplify asynchronous method declarations with Task.async()

In Mozilla code, Task.spawn() is becoming a common way to implement asynchronous operations, especially methods like the greet method in this greeter object:

let greeter = {
  message: "Hello, NAME!",
  greet: function(name) {
    return Task.spawn((function*() {
      return yield sendGreeting(this.message.replace(/NAME/, name));
    }).bind(this);
  })
};

Task.spawn() makes the operation logic simple, but the wrapper function and bind() call required to start the task on method invocation and bind its this reference make the overall implementation complex.

Enter Task.async().

Like Task.spawn(), it creates a task, but it doesn't immediately start it. Instead, it returns an "async function" whose invocation starts the task, and the async function binds the task to its own this reference at invocation time. That makes it simpler to declare the method:

let greeter = {
  message: "Hello, NAME!",
  greet: Task.async(function*(name) {
    return yield sendGreeting(this.message.replace(/NAME/, name));
  })
};

With identical semantics:

greeter.greet("Mitchell").then((reply) => { ... }); // behaves the same

(And it avoids a couple anti-patterns in the process.)

Task.async() is inspired by ECMAScript's Async Functions strawman proposal and C#'s Async modifier and was implemented in bug 966182. It isn't limited to use in method declarations, although it's particularly helpful for them.

Use it to implement your next asynchronous operation!

2014-03-27

qualifications for leadership

I've been surprised by the negative reaction to Brendan's promotion by some of my fellow supporters of marriage equality. Perhaps I take it too much for granted that Mozillians recognize the diversity of their community in every possible respect, including politically and religiously, and that the only thing we share in common is our commitment to Mozilla's mission and the principles for participation.

Those principles are reflected in our Community Participation Agreement, to which Brendan has always shown fealty (since long before it was formalized, in my 15-year experience with him), and which could not possibly be clearer about the welcoming nature of Mozilla to all constructive contributors.

I know that marriage equality has been a long, difficult, and painful battle, the kind that rubs nerves raw and makes it challenging to show any charity to its opponents. But they aren't all bigots, and I take Brendan at his word and deed that he's as committed as I am to the community's inclusive ideals (and the organization's employment policies).

As Andrew Sullivan eloquently states in his recent blog post on Religious Belief and Bigotry:

"Twenty years ago, I was confidently told by my leftist gay friends that Americans were all anti-gay bigots and would never, ever back marriage rights so I should stop trying to reason them out of their opposition. My friends were wrong. Americans are not all bigots. Not even close. They can be persuaded rather than attacked. And if we behave magnanimously and give maximal space for those who sincerely oppose us, then eventual persuasion will be more likely. And our victory more moral and more enduring."

I'm chastened to admit that I substantially shared his friends' opinion twenty years ago. But I'm happy to realize I was wrong. And perhaps Brendan will one day do the same. Either way, he qualifies to be a leader at any level in the Mozilla community (and organization), as do the many other Mozilla leaders whose beliefs undoubtedly differ sharply from my own.

2013-10-15

from Webapp SDK to r2d2b2g, Firefox OS Simulator, and the App Manager

A little over a year ago, on August 31, 2012, I brainstormed the outline of a "Webapp SDK":


That outline was the genesis for the r2d2b2g experiment, which built the Firefox OS Simulator, whose initial version hit the web on September 14, 2012 and which has gone through numerous iterations since then as we evaluated various features to enhance app development.

And that experiment spurred Mozilla's Developer Tools group, particularly its nascent App Tools team, to build Firefox's new App Manager, which landed last month and was introduced today on Hacks!

Despite the twisty passage from experiment to product, that initial outline bears a surprising resemblance to the App Manager feature set. The Manager checks off three of the four features on the outline's primary list—"start Gaia in B2G," "package app," and "test app in Gaia/B2G"—plus a few on its secondary list, like "debug from Firefox" and "test on mobile device," with "edit manifest in GUI" well underway over in bug 912912. And the Simulator continues to provide B2G/Gaia via an easy-to-install addon that integrates with the Manager.

Like any good product of a successful experiment, however, the Manager's reach has exceeded its progenitor's grasp! So it also gives you access to pre-installed apps, lets you take screenshots of device/Simulator screens, and will doubtless continue to sprout handy features to make app development great.

So kudos to the folks who built it, and long live the App Manager!

2013-08-23

fixing this morning's mach OS X psutil bustage

If mach is broken in your mozilla-central clone on Mac OS X this morning:
08-23 10:20 > ./mach build
Error running mach:

    ['build']

The error occurred in code that was called by the mach command. This is either
a bug in the called code itself or in the way that mach is calling it.

You should consider filing a bug for this issue.

If filing a bug, please include the full output of mach, including this error
message.

The details of the failure are as follows:

AttributeError: 'module' object has no attribute 'TCPS_ESTABLISHED'

  File "/Users/myk/Mozilla/central/python/mozbuild/mozbuild/mach_commands.py", line 293, in build
    from mozbuild.controller.building import BuildMonitor
  File "/Users/myk/Mozilla/central/python/mozbuild/mozbuild/controller/building.py", line 22, in <module>
    import psutil
  File "/Users/myk/Mozilla/central/python/psutil/psutil/__init__.py", line 95, in <module>
    import psutil._psosx as _psplatform
  File "/Users/myk/Mozilla/central/python/psutil/psutil/_psosx.py", line 48, in <module>
    _TCP_STATES_TABLE = {_psutil_osx.TCPS_ESTABLISHED : CONN_ESTABLISHED,

Then you've been bit by the fix for bug 908296. To resolve the bustage, run this command in your Hg clone:
hg status -in python/psutil | xargs rm

Or, if you've cloned the Git mirror, run this instead:
git clean -xf python/psutil

2013-06-07

64-bit Linux ADB for Simulator

Thanks to the efforts of new Mozilla intern Brandon Kase, the latest preview build of Firefox OS Simulator for Linux includes a 64-bit version of ADB, so you can push an app to an FxOS device from 64-bit Linux installations without any extra packages!

Building it was tricky, because the Android SDK build scripts don't support that target. Brandon first tried simply specifying the target, which worked on an older version of ADB (1.0.24). But it failed on the latest version (1.0.31), which links with a bundled copy of libcrypto that includes 32-bit assembly.

Ubuntu 13.04 (Raring) ships a 64-bit android-tools-adb package, though, so we knew it could be done. And its source package's build system is much simpler than the SDK's. We just needed a binary that works on distributions with older versions of glibc than Raring's 2.17. And one that doesn't depend on a specific version of libcrypto, which varies around the Linux world; whereas Raring's ADB executable appears to need the specific version that comes with that distribution.

So Brandon modified the source package's Makefile to link libcrypto statically (note the absolute path to libcrypto.a, which may vary):
--- debian/makefiles/adb.mk    2013-03-26 14:15:41.000000000 -0700
+++ adb-static-crypto.mk    2013-06-06 16:51:52.794521267 -0700
@@ -40,15 +40,16 @@
 CPPFLAGS+= -I.
 CPPFLAGS+= -I../include
 CPPFLAGS+= -I../../../external/zlib
+CPPFLAGS+= -I/usr/include/openssl
 
-LIBS+= -lc -lpthread -lz -lcrypto
+LIBS+= -lc -lpthread -lz -ldl
 
 OBJS= $(SRCS:.c=.o)
 
 all: adb
 
 adb: $(OBJS)
-    $(CC) -o $@ $(LDFLAGS) $(OBJS) $(LIBS)
+    $(CC) -o $@ $(LDFLAGS) $(OBJS) /usr/lib/x86_64-linux-gnu/libcrypto.a $(LIBS)
 
 clean:
     rm -rf $(OBJS) adb

Then I copied the source package to my CentOS 16 build machine (which has glibc 2.12) and built it there. After which the resultant executable worked on all the distributions we tested: Ubuntu 13.04, Ubuntu 10.04, CentOS 16, and Arch Linux (kernel 3.9.3-1-ARCH).

Presumably it will work on others too. But if it still doesn't work for you, let us know!

And if you just want the ADB executable, sans Simulator, here it is.

2012-10-02

r2d2b2g implementation details

Over at Mozilla Hacks, I just blogged about r2d2b2g (ratta-datta-batta-ga), an experimental prototype test environment for Firefox OS that makes it drop-dead simple to test your app in B2G Desktop.

r2d2b2g is an addon, but it bundles B2G Desktop nightly builds, which are native executables, and thus the addon is platform-specific, with packages available for Mac, Linux 32-bit, and Windows (caveat: B2G Desktop for Windows currently crashes on startup due to bug 794662 795484).

The packages are large, 50-60MB each, partly because of the executables, but mostly because they also bundle Gaia profiles, including all default apps. (It's probably worth bundling a few of these, for demonstration purposes, but we could make the packages much smaller by removing the rest.)

r2d2b2g uses the Add-on SDK as its addon framework and relies on several third-party addon modules (subprocess, menuitems) along with some Python utilities (mozdownload, mozbase) to download and unpack B2G Desktop builds. Plus Gaia, although recent work to bundle Gaia profiles with B2G Desktop builds may break that dependency.

I've demoed the project to a variety of folks over the last couple weeks, and I've received a bunch of positive feedback about it. B2G Desktop combines approachability with phoneliness and is the best existing test environment for Firefox OS. But its configuration is a challenge, and it provides no obvious affordances for installing and testing your own app. r2d2b2g shows that these problems are tractable (even if it doesn't yet solve them all) and demonstrates a promising product path.

After seeing r2d2b2g, Kevin Dangoor drafted a PRD for a Firefox OS Simulator that I'll use to guide further development. Interested in participating? Clone the code from its GitHub repository and contribute your improvements!

2012-03-07

Next/Previous Tab on Mac Consistent At Last

After blogging about the inconsistency of keyboard shortcuts for Next/Previous Tab on Mac last year, I found out that Firefox, Thunderbird, and Komodo also support Command + Option + LeftArrow|RightArrow, and Adium has a General > "Switch tabs with" pref that I can set to the same chord.

(Later, I switched IM clients from Adium to InstantBird, which also supports that combination.)

That left Terminal, which I couldn't figure out how to configure to support the same shortcut. Until now.

I'm not sure if it's because I have since upgraded to Mac OS X 10.7 (Lion). I could've sworn I tried something like this back when I wrote that previous blog post, and it didn't work.
  1. Go to System Preferences > Keyboard > Keyboard Shortcuts > Application Shortcuts.
  2. Press the + (plus) button.
  3. Select "Other..." from the Application menu and select Utilities > Terminal from the file picker dialog.
  4. Enter "Select Next Tab" (without the quotes) into the Menu Title field.
  5. Focus the Keyboard Shortcut field and press Command + Option + RightArrow to set the keyboard shortcut, which will appear as ⌥⌘→.
  6. Press the Add button.

Repeat steps 4-6 with "Select Previous Tab" and Command + Option + LeftArrow, which will appear as ⌥⌘←.

Those shortcuts should now work in Terminal.

With this change, all five of my current primary productivity applications on Mac (Firefox, Thunderbird, Instantbird, Komodo, and Terminal) support a consistent pair of keyboard shortcuts for Next/Previous Tab, which are two of the most common commands I issue in all of those apps.

Woot!

generating a fingerprint for an SSH key

After recently discovering a security vulnerability that allows an attacker to add an SSH key to a GitHub user account, GitHub is requiring all users to audit their SSH keys. Its audit page lists one's keys by type and fingerprint, but it doesn't say how it generated the fingerprint or how to generate one for your local copy of a key to compare it with. Nor does it let you see the whole key.

And since I don't generate such fingerprints very often, I didn't know how to do it. So I tried cksum, md5, and shasum on my Mac, but none of their checksums matched. Turns out the tool to use is ssh-keygen:

    ssh-keygen -l -f path/to/keyfile

2011-10-17

Mozilla Status Board Text is Markdown

It isn't documented anywhere that I can find, but Benjamin Smedberg's handy Mozilla Status Board tool parses status text as Markdown, which is how I added a Didn't header to the Done section of my status update with all the things I planned to do last week but didn't make happen. (The Done, Next, and Coordination headers are all H4s, so I prepended four hash marks to #### Didn't to make it the same size).

(Note that [Markdown-style links](http://daringfireball.net/projects/markdown/basics) don't work and cause the entire section in which they appear to remain unparsed. However angle-bracketed URLs, as recommended by RFC 3986 <http://labs.apache.org/webarch/uri/rfc/rfc3986.html#delimiting>, work when added to the ends of lines. And "bug ###" references are auto-linkified.)

2011-09-16

to all the bugs I've filed before

The first bug I filed was marked as duplicate; the second was worksforme (although Chris Petersen could reproduce it before he couldn't anymore); and the third was invalid (it was the spec, not the code, that was errant). The fourth is the first that was fixed.

2011-09-09

"Next/Previous Tab" Keyboard Shortcuts on Windows

On my Windows laptop, I use the following four programs with tabbed interfaces on a regular basis:
  • Firefox
  • Thunderbird
  • Instantbird
  • Komodo IDE
(I'd love to have tabs in my Windows terminal app of choice, Mintty, but its developer thinks tabs should be implemented at the window manager level.)

Unlike on my Mac, all those programs implement the same keyboard shortcut for switching to the previous/next tab, and it's a simple one with just a two-key chord: Control + PageUp / PageDown.

Ha!