Power Nap and the Network

October 18, 2012

With the introduction of Power Nap developers have something new to think about: applications running while the system appears to be asleep. Every hour Power Nap enabled systems partially wake up and any running applications will briefly execute with disk and network access. In most cases this works just fine, but for some apps it can result in behavior that the user does not expect. For example, consider apps like instant messaging and IRC clients that advertise the presence of a person or service. Every hour they will reconnect to their networks and make it appear as if the user is available when they really aren’t. Such reconnections can also cause downright annoying behavior like the AIM multiple sign-in warning, improper redirection of incoming messages, or an offline IRC buffer being sent to the wrong device.

For apps like these the behavior is likely caused by the application attempting to reconnect in response to a closed connection or low-level network state notifications. Previously this worked as expected because the reconnection code did not run until the user woke up the system, but under Power Nap it is running while the system is still asleep from the user’s point of view. Apps that run into trouble here will need to suspend their reconnect behavior until the system is fully awake, and fortunately this is pretty easy to do. The partial wake state used by Power Nap is known as Dark Wake, and while in this state the NSWorkspaceDidWakeNotification and SCNetworkReachability callbacks are not sent. As a result a simple solution is to watch for the NSWorkspaceWillSleepNotification and disable reconnects or network state observers until an NSWorkspaceDidWakeNotification is received. Alternatively an application can adopt the SCNetworkReachability APIs if possible and rely on those callbacks to inform the app when it is appropriate to reconnect.

If you want to test your changes without waiting an hour for Power Nap to kick in an easy way to trigger Dark Wake for a few seconds is to put the system to sleep then connect or disconnect AC power or a peripheral. This is also useful for testing a direct transition from Dark Wake to full wake by connecting power then pressing a key to wake up the system.