Posted on | February 20, 2010 | 1 Comment
Say what you will about Python being better suited to writing back end control panels that need to get intimate with the host OS .. I still use PHP. Mostly, I’m too lazy to master Python to the point that I’m willing to put my results in production and , well, if used properly – PHP does the job just fine.
A lot of people know about the set_time_limit() function, useful if you know that your script is going to need to block while waiting for something else to happen. This is halfway dangerous in itself, I see a lot of people using it rather than trying to figure out why their queries are taking so long, or why its taking so long to process images, or whatever. Still, useful when used properly. What most programmers forget, however is that users love to close their browser and have monkeys in their offices that unplug ethernet cables.
That’s when ignore_user_abort() comes into play. Lets say you’re doing what I’m doing, writing a simple control panel to help manage a very rudimentary OS. You want to give people a way to compile certain packages from source from the same menu that they use for everything else that they install. With a few clicks, the system is downloading, configuring, compiling and installing a kernel.
It would be a real pain if the user were to be disconnected when this process was 90% complete. What is easier, writing code to resume an aborted build, or just making sure the build doesn’t abort unless there really is some error worth evaluating?
If you are too lazy to read the manual, here it is in a nutshell:
// See how the behavior is set,
// abort_setting will be true or false
$abort_setting = ignore_user_abort();
// Keep going, even if the user didn't ignore_user_abort(true);
// Return to default behavior ignore_user_abort(false);
That, alone helps to make sure that you accomplish what the user told you to accomplish. Meanwhile, you have to take into consideration that the user might actually want you to abort. For this, POSIX signals become your friend. If you are going to use ignore_user_abort(), you’ll probably want to set up signal handlers anyway (at least, you should!).
Prior to calling ignore_user_abort(), present a form with an abort button, or a link that says “Abort” which is aware of the current PID. If clicked or POSTed, let something handle the request and deliver the signal to the blocking process. For instance, SIGUSR1 could mean “Ok, they really want to abort”. Additionally, you can use the non-fatal signals to communicate with back end shell scripts, i.e. to advance a progress indicator that is displayed to the user.
One of the things that annoys me so much about some proprietary control panels is the alert() raised when I start a build: “Do not navigate away from this page or close this window, if you do, this process will abort” – the same appears during any bulk/batch operation. What the message should say instead is “Call your ISP and tell them that you better not lose connectivity for the next 30 minutes, if you do – I’ll die, because the person who wrote me was too lazy to handle it“
Despite some statistics, more people have no / bad connections vs people who have great broadband. Even if you have fiber in your home, you’d appreciate a “smarter” script if you were trying to accomplish something on Starbucks wifi with a smart phone. Isn’t it better to just start it and forget it?