rubygems/rubygems — pull request #352 by alexch (2012-07-06 03:13:51+00:00)
Title: If the OS allows it, build the docs (ri and rdoc) in a forked background process

ri and rdoc are amazingly great, but sadly, many people are impatient, so the Ruby world is filled with advice to add --no-rdoc and --no-ri everywhere, and people are then forced to use their web browsers and visit ruby-doc.org when a quick "ri titleize" would suffice, with much less risk of flow interruption.

This patch attempts to resolve this tension between install-time and dev-time impatience by forking a background process to build the docs after the gems have been installed. The only risk will be if someone tries to use ri or rdoc during the seconds or minutes immediately after the install, which is unlikely and at any rate, there are enough messages that people should realize the docs aren't quite built yet. And all that would happen is that the docs wouldn't be found; no risk of corruption or even misleading errors as far as I can tell.

The code is fairly elegant but it currently relies on the fact that the only user of the done_installing_hooks is the documentation builder. If any other code wants to add hooks then we'd have to make it a little more configurable -- possibly allowing different status messages, possibly adding a new hook array for just backgroundable tasks and restoring done_installing_hooks to just run synchronously like before.

Is there a need to add a "--no-background" option? I can't think of a real use case. If we're on Windows (or another forkless Ruby) it'll revert to synchronous. Perhaps rubygems.org needs to build docs synchronously, but if it's using the RDoc code directly this patch won't affect it.

One thing I feel strongly about is that backgrounding doc gen should be the default behavior. If we hide this behind an option then we're just perpetuating the original problem -- the perception that "gem install" is slow so you should just not install docs. (Which you actually should.)

There are no unit tests yet. It's kind of difficult to unit test `fork` but if you insist I could try to give it a go. Maybe we'd mock fork just to assert that it was called without actually forking anything during the test.

I just tried a clean install of rails and here are some stats:

time to install 2 dozen gems: 13sec
time to build docs for same: 238sec

So I guess it's no wonder people prefer --no-rdoc...