Using Task mechanism slows backend process if app is not the foreground app.

A while back, I started using the Task-based Dictionary / Timer mechanism to update UI elements in long running tasks executed in a shell. However, I’ve just noticed that a test app built using Xojo 15r4.1 under 10.10 .5 and 10.11.4 results in the performance of the app slowing to a crawl (time required to complete the task doubles) if the app is not the foreground app.

My suspicion is that the issue is in the way that the Task updates rather than the Timer / Dictionary since the backend process slows, not just the UI updates (otherwise the UI updates would simply skip huge chunks of the output from the backend task).

I re-ran the test code in 13r3.3 as well as 14r1 and they exhibit the same issues, so this isn’t a new issue with 15r4.1.

Is anyone else using the Task procedure to run a background process witnessing this type of problem?

Are you just hitting “app nap”? There doesn’t seem to be a way built into Xojo yet to avoid that when a task is actually running in the background. You can turn it off in the finder for the compiled app or use the MBS plugins to turn it off or probably some declares somewhere. I wasted 2 hours the other day debugging a throughput problem that was just completely that :wink:

Excellent tip - I’d forgotten that the setting doesn’t apply to debugged apps. Digging into that now.

Hmmm, when the app is built with 15r4.1, there’s no option for disabling App Nap…

https://forum.xojo.com/7802-prevent-app-nap/0
http://krypted.com/mac-os-x/disable-app-nap-in-mavericks/
https://forum.xojo.com/18925-prevent-app-nap-and-2014r3v1/0
http://osxdaily.com/2014/05/13/disable-app-nap-mac-os-x/
https://forum.xojo.com/10898-mavericks-is-putting-my-app-to-sleep/0

among others…

Is this a console app or a GUI app?

It’s a GUI app. Here’s a shot of what Get Info provides after the build:

The NSProcessInfoMBS mechanism did not resolve this issue. Watching the process info in Activity Monitor doesn’t indicate any differences in the Idle Wake Ups count regardless of foreground or background.

Switching back to building with 13r3.3 returns the property for App Nap to the app properties. Disabling App Nap in this manner resolves my performance issue completely.

Examining the Info.plist files, aside from the minimum OS required I don’t see the difference between the two builds in how the system determines whether the “Prevent App Nap” is displayed or not.

You can programatically disable it IN your app
That might work best for this

Or at least work WITH app nap
Check out ProcessInfo beginActivityWithOptions and endActivity
This gives yo uthe ability to tell app napp to NOT slow you down while this activity is running

Tried that first using both Christian’s MBS version and the set of declares (thanks to @Michel Bujardet’s links above). No luck in the result - if the window wasn’t frontmost, the backend slowed to crawl. Only by building on 13r3.3 do I get an app that works as expected by disabling App Nap.

As for what’s best for our apps - they are already designed to be 0 resource use apps when not actively performing the backend file / device I/O operations. However, when the background processes are running, they must be uninterrupted and non-throttled. At full bore, our backend tool only uses around 15% of a single CPU core and around 30MB of RAM.

App Nap is a crutch to allow the OS to manage poorly designed apps that were not written with small model systems in mind. Our core components have to run on a 256MB/250MHz system, so anything larger is just gravy for BRU-based apps. This same design requirement folds over to my work in the GUI world. My UI's might not be the prettiest things floating around, but I can promise that they won't bog a system down.

What options did you use ?
I’d OR all these together
NSActivityIdleSystemSleepDisabled = (1ULL << 20),
NSActivitySuddenTerminationDisabled = (1ULL << 14),
NSActivityAutomaticTerminationDisabled = (1ULL << 15),
NSActivityUserInitiated = (0x00FFFFFFULL | NSActivityIdleSystemSleepDisabled ),
NSActivityBackground = 0x000000FFULL,
NSActivityLatencyCritical = 0xFF00000000ULL,

I used the Apple-recommended flags for what I’m trying to do.

NSActivityIdleSystemSleepDisabled | NSActivityBackground

Hadn’t thought of Using LatencyCritical, but we haven’t needed it as the performance is where it should be without it.

BTW - NSActivitySuddenTerminationDisabled is a bad thing unless you REALLY know what the consequences are in that it can even keep Force Quit (kill -KILL) from terminating an app.

Also, it’s more than the Info.plist files since I copied the file from the 13r3.3 build over and the App Nap option is still not shown.

[quote=247198:@Tim Jones]App Nap is a crutch to allow the OS to manage poorly designed apps that were not written with small model systems in mind. Our core components have to run on a 256MB/250MHz system, so anything larger is just gravy for BRU-based apps. This same design requirement folds over to my work in the GUI world. My UI’s might not be the prettiest things floating around, but I can promise that they won’t bog a system down.
[/quote]

It has nothing to do with MHz or bogging a system down. It’s actually quite the opposite: on a modern CPU, you want to do all the work at once and then let the CPU go back to lower power states. Frequent timers mean the CPU is constantly going up and down power states and that’s a big energy waste. It also relates to thermal pressure, which is a bad thing in laptops or computers without fans.

I believe NSActivitySuddenTerm??inationDisabled only refers to AppKit’s sudden termination feature. This is an optimization that application developers can opt into which lets the system kill the process instead of sending Apple Events to it and doing all the normal teardown work involved in quitting.

And that’s what we do - we do things as fast as possible for a given situation. If the GUI is doing nothing, I’ve gotten it down to as close to 0% CPU as possible with the RS/Xojo frameworks and the controls / methods that I use. When the backend tools are running, they are processing the data as quickly as the filesystems / storage environment allows within the understood limits that our operations can take days to complete - processing and writing 1/2 PB onto LTO tape, for example. We copy the data from the filesystem to the tape as fast as the tape (or filesystem, depending) permits while leaving the system responsive for other user tasks.

Ours is quite dramatically a corner case compared to the 98th percentile of applications out there. Even when editing 8K video and 7.1 audio, application tasks occur in bursts measured in fractions of seconds to low minutes. With an application that is designed to catalog, inspect, validate, and archive literally 10’s of terabytes in a 12 hour period, we don’t have a lot of the idle app luxury of other applications. Therefore, App Nap is a very bad idea for us.

I understand about what NSActivitySuddenTerminationDisabled is designed for, but it also has been reported as having “side effects”.

This is the key to use “NSActivityUserInitiated”, it gives the app full watchyamecallit. We use this in our backup to go.

Update -

After trying all sorts of combinations of the NSProcessInfo and either never getting 100% results or actually getting hangs in the app, I’ve finally resorted to using a shell and setting the defaults entry for my app to completely disable App Nap.

If I was worried about saving the planet 1 mw at a time, this might be worth more research, but since my apps run on desktop systems 95% of the time and plugged in laptops the other 5%, I’m not worried about saving a few minutes of battery time.

For those who may be curious -

#if TargetMacOSX
theShell.Execute “defaults write " + your_Application_Identifier + " NSAppSleepDisabled -bool YES”
#endif