The documentation for the interruptionHandler
block of NSXPCConnection
states:
An interruption handler that is called if the remote process exits or crashes.
However, the Daemons and Services Programming Guide states:
XPC services are managed by launchd, which launches them on demand, restarts them if they crash, and terminates them (by sending SIGKILL) when they are idle. This is transparent to the application using the service, except for the case of a service that crashes while processing a message that requires a response. In that case, the application can see that its XPC connection has become invalid until the service is restarted by launchd
If an XPC process is killed for being idle, will I get a callback in my interruptionHandler
? Or will I only get the callback when the app crashes while processing a message? I ask because this test case seems like it's impossible to simulate. XPC service lifecycle is unfortunately a very black box.
Yes the interruption handler will be called if launchd stops the service for being idle.
This can be simulated by leveraging the natural reaction launchd has to memory pressure: stopping all launchd launched services that are idle to help relieve the issue.
A simulated warn level of memory pressure should be enough, here is how you do it:
sudo memory_pressure -S -l warn
And for critical:
sudo memory_pressure -S -l critical
This condition is often missed when testing XPC Services. However it is recommended XPC services are designed to be stateless, so in most cases it should not matter if your service is stopped and can be restarted by launchd the next time you send a message. And ideally you invalidated the connection when you were last done with it.
Launchd will not stop an XPC service with the above conditions if there is an ongoing XPC transaction (read: a message is being handled and/or the reply block has not been invoked).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With