Monday, April 9, 2012

Is mdworker Jeopardizing Your Resources? Run It at a Lower Priority

Since I've installed OS X Lion, I've been complaining about the performance degradation I was observing. More often than not, I find the guilty to be mdworker, the (in)famous Spotlight's indexer process, which may use lots of CPU cycles and generate lots of IOPs. Perhaps, unless you're using an SSD, the hard disk is going to be the bottleneck in many situations. Even if it's not, I've seen mdworker using an entire CPU core for entire seconds: it's a lot of computational time, and even a human being is going to notice the performance degradation of his machine when mdworker stubbornly keeps on using CPU time over and over again.

It's important to realize that the job of mdworker is observing changes in the file system and reflect those changes into Spotlight's content indexes. That's not the problem. The problem is that, by default, mdworker appears to be running with the same priority and I/O priority than most your user space processes. Depending on your computer usage pattern, you may or may not observe any performance degradation caused by mdworker: in fact, I bet most users won't notice it, but when you do, it's a real pain.

In my case, I notice a huge performance degradation when using programs that can generate massive changes in the file system in a short period of time, such as Adobe Lightroom or Apple Aperture. I found myself watching the Lightroom window freezing so often, waiting for mdworker to finish its job and relinquish some resources, that I decided to look for a solution to this problem.

Fortunately, there's a quick workaround that works pretty well and addresses the core issue with mdworker: its priority.

OS X Tiger (10.4) introduced a service management framework, launchd, that essentially replaced a bunch of legacy service handling daemons such as init, inetd, xinetd, and all the related scripts. launchd centralizes service management and, as such, it also centralizes service configuration using a property list files. If you're new to OS X development, property list essentially are XML files using a schema defined by Apple.

If you want to customize the behavior of an OS X service, you can just modify the corresponding configuration file without any deeper knowledge of the service behavior. You can read the launchd.plist official documentation for a list of valid configuration keys.

Although we're focusing on mdworker here, the concepts herein can be applied to any service you'd like to configure.

Modifying a Service Configuration File

Service configuration files are currently stored in two directories:

  • /System/Library/LaunchAgents
  • /System/Library/LaunchDaemons

First of all, you've got to locate the configuration file of the service you want to customize. Open the file in your favorite XML editor and carefully modify it. An invalid property list file will result in launchd rejecting the invalid configuration and the corresponding service failing to start.

With the release of XCode 4, the Property List Editor is no longer available as a separate application and all the editing is performed inside XCode. If you've got XCode, it's very easy to modify property list files using its GUI. If you haven't got XCode, it's a bit overkill to install such a huge application only to modify a property list file. I'd rather use an alternative XML editor and carefully review the changes before applying them.

In any case, I'm including my entire configuration file in this blog post so that you can just copy it over yours.

Reducing the mdworker Priority

The configuration file of mdworker (the Spotlight's indexer) is:

/System/Library/LaunchDaemons/com.apple.metadata.mds.plist

As we can see in launchd.plist documentation, we can take advantage of two configuration keys to lower the working priority of this process:

  • LowPriorityIO
  • Nice


For CPU-intensive processes, Nice can be the solution, since it specifies the service's scheduling priority. The higher the nice level, the lower its priority. Nice can take values in the [-20, 20] range.

Since mdworker is also a I/O-intensive process, we will use the LowPriorityIO configuration key as well. This configuration key takes a boolean value and, when set to true, it instructs the kernel to consider the process as low priority when performing file system I/O. That's just what we need to avoid mdworker jeopardizing our resources when using I/O intensive processes such as Adobe Lightroom.

The resulting configuration file is the following:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>KeepAlive</key>
  <true/>
  <key>Label</key>
  <string>com.apple.metadata.mds</string>
  <key>ProgramArguments</key>
  <array>
    <string>/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Support/mds</string>
  </array>
  <key>MachServices</key>
  <dict>
    <key>com.apple.metadata.mds</key>
    <true/>
    <key>com.apple.metadata.mds.xpc</key>
    <true/>
    <key>com.apple.metadata.mds.xpcs</key>
    <true/>
  </dict>
  <key>SoftResourceLimits</key>
  <dict>
    <key>NumberOfFiles</key>
    <integer>2048</integer>
  </dict>
  <key>HardResourceLimits</key>
  <dict>
    <key>NumberOfFiles</key>
    <integer>2048</integer>
  </dict>
  <key>LowPriorityIO</key>
  <true/>
  <key>Nice</key>
  <integer>20</integer>
</dict>
</plist>

Here's the same file as seen in XCode:

XCode 4 - Property List Editor (Integrated)

Conclusion

The next time the service restarts the new configuration will take effect. The easiest way to do it is just reboot. mdworker will now work as usual, but won't steal your resources as aggressively as before.

You can check that mdworker is now running with a lower priority examining ps output (6th and 7th column):

$ ps -axl | grep mdworker

  UID   PID  PPID        F CPU PRI NI       SZ    RSS WCHAN     S             ADDR TTY           TIME CMD

  501   234   232    84004   0   4 17  2485976  25916 -      SN   ffffff800f0bbdc0 ??         3:56.98 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker -s mdworker -c MDSImporterWorker -m com.apple.mdworker.pool.0
   89   881   879    84004   0   4 17  2479740   6420 -      SN   ffffff800fd84200 ??         0:00.14 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker -s mdworker -c MDSImporterWorker -m com.apple.mdworker.pool.0


Thursday, April 5, 2012

Readability: An Alternative to Safari Reader for Google Chrome Users

The title of this blog post is intentionally misleading: Readability, in fact, was the project that "inspired" the Safari Reader. Nevertheless, many OS X users start using Safari as their first browser and, when switching to other browsers such as Google Chrome, tend to thinking that Safari Reader was the first implementation of such an idea.

Google Chrome has been experiencing a rapid growth since its inception and I recognize it's a great browser that shines, above all, for its speed. However, I never really switched away from Safari for the same reason I haven't switched away from iChat, iCal or Mail, either. Which one? Because of its tight integration, even across multiple Apple devices.

However, running multiple browsers side by side poses no problems and it's pretty common nowadays (most web developers are compelled to do so while testing their applications). Despite being a strong Safari user, Chrome is the browser I use while accessing Google's own services (such as Google+, GMail, Calendar and Blogger).

When Safari Reader made its appearance, I wasn't really impressed and wondered whether I would really use it. I was wrong. I find it's very useful. Not only to actually read a cleaned-up version of a web page (many websites already provided a specific CSS for printing that you can use for this purpose). Safari Reader lets you convert its output to PDF (using the standard OS X print dialog) or send that PDF by email with just one click.

Safari Reader - Toolbar

When I started using Google Chrome, the Reader was the feature I missed the most.

Readability

Readability is a Chrome extension that provides Reader-like features to Google Chrome. In fact, as stated earlier, Readability is the project that inspired Safari Reader (sometimes, though, inspirers are more obscure that fine-tuned copies). To install readability, just open the Chrome Web Store, search for Readability, and install it:

Chrome Web Store - Readability Application

Once you install it, it will be immediately available without even restarting your browser.

You can access the Readability features by using its icon in the Chrome toolbar or using one of its keyboard shortcuts (more on this later).

Chrome Toolbar - Redability icon

Clicking the Readability icon will open its main menu and you soon realize that it offers more than the Safari Reader does: you can Read Now (the equivalent feature of Safari Reader), you can Read Later (Safari also offers this: it's called Reading List) and you can Send to Kindle.

Redability Menu

In this post we will only focus on the Read Now feature. Here's the same New York Times articles as shown by Readability:

Readability

In my opinion, apart from correctly displaying far more pictures than Safari Reader does (as well as some ad too), Readability produces better-looking previews of most web pages I visit.

The features that the "preview" window offers are superior to Reader's:
  • You can print the article (and produce PDF files).
  • You can tweak the page appearance.
  • You can send the converted article by mail.
  • You can share it on social networks (Twitter and Facebook are currently supported).
  • You can produce a short URL to it.

Small Glitches on OS X

I don't know how many OS X are really affected by this issue (given their historic idiosyncrasy to using the keyboard :), but Latin languages speakers (such as Italian and Spanish) surely are.

First of all: the OS X keyboard shortcut to cycle between the windows of an application is ⌘-` (Command-`). Guess which is the default keyboard shortcut that Readability assigns to some of its functions? Yes, you're right. The ` character.

I really don't know what the developers were thinking about when they chose this character. They surely aren't Latin languages speakers, otherwise they would have devised how often this character is used. And they surely aren't Mac users either, otherwise they would have realized how annoying it is, too.

Don't worry, though. They're really easy to change. Just right-click over the Readability icon and choose Options. In the configuration window, just assign the keyboard shortcuts you like or do as I did: disable them all.

Readability - Keyboard Shortcut Configuration

Conclusion

This blog post is not about which browser you should use: it's your choice and, as I stated, you can run multiple ones side-by-side. However, many Safari users switching from Safari often look to alternatives to the Safari Reader as well.

If you're using Chrome, you're lucky because the Readability extension provides the same features provided by the Safari Reader (and even more). Moreover, in my opinion the layouts produced by Readability are superior and far better looking than those produced by Safari Reader. You'll be surprised.