IIS 7 and Above
Anyone actually get SignalBeforeTerminateSeconds working?
Last post May 13, 2010 01:18 PM by don.raman
May 12, 2010 12:24 PM|tony_ser|LINK
May 12, 2010 01:15 PM|don.raman|LINK
Whatever you are seeing is the intended behaviour. When SignalBeforeTerminateSeconds is set to a value greater than 0, IIS sends _FCGI_SHUTDOWN_EVENT to the child process before terminating them forcibly and wait for seconds configured as part of SignalBeforeTerminateSeconds.
This gives the FastCGI dying process to exit themselves cleanly. For example if a FastCGI process (here php-cgi.exe) wants to do some cleanup like close some open handle, give back some taken resource, free some shared memory etc. can now do the cleanup before
dying. So the cleanup code has to be written by an application developer. In a nutshell, do whatever you want to do as IIS now gives you a way to do things before forcibly shutting down the FastCGI process.
Hope this explain things. Treat this as kind of signal. IIS is giving you signal and you as an application developer needs to write your own signal handler to deal with this signal if required.
May 12, 2010 01:46 PM|tony_ser|LINK
I understand that part (I think) but I thought the child process is supposed to exit when they are finish cleaning up so that IIS does need to wait for the max time. I was expecting SignalBeforeTerminateSeconds specify the maximum wait time before force
kill. And if the FastCGI process cleanup sooner, IIS does not have to wait that long.
Or is it designed to alway wait that long?
May 12, 2010 01:52 PM|ksingla|LINK
If process exits early, FastCGI will detect that and short circuit the wait.
May 12, 2010 01:52 PM|don.raman|LINK
IIS will wait for specified seconds if process doesn't go away. How is IIS going to know that you are done with the cleanup? There is no callback to IIS from FastCGI process that 'I am done and so terminate me'. Rather just call PHP function
exit after you are done with clean-up code and the php-cgi.exe will go away. And you will not need to wait for seconds specified. This feature is intended to give application user a control to terminate their PHP process rather than IIS forcibly terminating
May 12, 2010 02:05 PM|tony_ser|LINK
Perfect. Now that we straighten out this part. We can go back to my original question.
That is "has anyone able to get SignalBeforeTerminateSeconds working with php-cgi.exe." (Sorry, I should have mentioned php-cgi.exe in the subject)
What I mean is anyone able to setup SignalBeforeTerminateSeconds=15 and saw php-cgi.exe exit before 15 seconds and IIS does not have to wait full 15 seconds.
I know SignalBeforeTerminateSeconds is a FastCGI feature, how a FastCGI process (php-cgi.exe in this case) behaves is beyond the control of FastCGI module itself. But given PHP is probably the most commong FastCGI process, I am just wondering if someone
actually get it working in this setup. Because I cannot get php-cgi.exe to exit earlier.
May 12, 2010 02:14 PM|don.raman|LINK
Can you share a sample piece of code so that we know what are you trying to do?
May 12, 2010 03:02 PM|tony_ser|LINK
Sure, but actually nothing special. Default installation of PHP 5.2.12 FastCGI mode
Here is the fastcgi section in applicationHost.config
<application fullPath="C:\Program Files (x86)\PHP\php-cgi.exe" monitorChangesTo="php.ini" maxInstances="4" idleTimeout="6000" activityTimeout="600" requestTimeout="90" instanceMaxRequests="10000" signalBeforeTerminateSeconds="30" protocol="NamedPipe"
<environmentVariable name="PHPRC" value="C:\Program Files (x86)\PHP\" />
Just create a php page with <? phpinfo(); ?>
Browse the page and then either do a "iisreset" or add a comment to php.ini save it to trigger the recycle due to "monitorChangesTo"
Watch the php-cgi.exe in taskmanager and notice they won't exit until 30 seconds.
I also loaded the debug symbol and php source.
HANDLE shutdown_event = (HANDLE) arg;
in_shutdown = 1;
The event did get triggered but php-cgi.exe did not exit itself.
The reason we are testing this is we implemented a php extension and we do have resources that need to cleanup on shutdown. Ever since we switched to FastCGI model we notice the force kill and have made request on iis and php forum for a solution that allow
proper cleanup. SignalBeforeTerminateSeconds sounds perfect and that is when we try it out and notice this FIX delay behaviour with just the default php-cgi.exe without our extension.
Also notice that even php-cgi.exe gets the event, within that 30 seconds, PHP_MSHUTDOWN_FUNCTION of any extension is not being called. Again, not with our extension, just the default php_date, the PHP_MSHUTDOWN_FUNCTION did not get called. But that is a
May 12, 2010 05:53 PM|don.raman|LINK
The event did get triggered but php-cgi.exe did not exit itself.
Why do you expect that mere trigger of the event will exit php-cgi.exe? The event is just a signal from IIS FastCGI that I am going to forcibly kill you after 'n' number of seconds as configured in property signalBeforeTerminateSeconds, so do all the clean-up
required and stay (so that IIS FastCGI can kill the php-cgi.exe) or call an exit in which case php-cgi.exe gets killed itself without waiting for 'n' seconds. I would say just do the clea-up and let IIS FastCGI actually exiting the php-cgi.exe. The reason
is if your extension does a force exit, other extension may not get a chance to clean-up properly.
The other question is how did you know that event got triggered? The reason you are seeing a 30 seconds delay is because IIS FastCGI DLL is waiting for 30 seconds as configured before forcibly killing the process. This doesn't guarantee that event is generated
unless you listen to it and ensure that event is indeed generated.
The reason we are testing this is we implemented a php extension and we do have resources that need to cleanup on shutdown.
Look IIS has just sent the event. This event is not going to trigger php-cgi.exe exit automatically and hence your extension shutdown function will never get called. Also after configured 'n' seconds a forceful exit of php-cgi.exe will be called and again
your extension shutdown function will not be called. Because of this reason setting signalBeforeTerminateSeconds to 30 is delaying your problem for another 30 seconds.
I am no expert at event handling and all but here is what you will need to do in order to handle this in your extension:
Hopefully this helps. And again thanks for enlightening me a bit too :).
May 12, 2010 09:06 PM|ksingla|LINK
Looks like a bug in php-cgi.exe. PHP should trigger a shutdown and exit on receiving this event.
May 13, 2010 12:23 AM|tony_ser|LINK
Why do you expect that mere trigger of the event will exit php-cgi.exe?...The reason is if your extension does a force exit, other extension may not get a chance to clean-up properly.
You are absolutely right. Extensions should not force exit. I was expecting php-cgi.exe (since it receive event instead of being force killed) now has a chance to call PHP_MSHUTDOWN_FUNCTION of each loaded extension and then exit.
The other question is how did you know that event got triggered?
Because I put a break point in the thread in php-cgi.exe and the WaitForSingleObject call monitoring the shutdown event returned.
Your suggestion of listening to the event in my extension make sense and it is exactly what I think I will need to do.
But it does not change the fact that anytime SignalBeforeTerminateSeconds is setup, IIS must always wait that fix time before exit. Again, with php-cgi.exe the most commonly used FastCGI process, I was just surprised with the behaviour. I thought I may have
miss some setup procedure. Hence, my subject "anyone actually get SignalBeforeTerminateSeconds working (with php-cgi.exe)", hoping if someone has experience on this can shed some light.
Appreciate your points and suggestions!
May 13, 2010 12:30 PM|don.raman|LINK
As my developer suggested this seems like a bug in php-cgi.exe. I am talking to him. I will update you with the findings and further action.
Thanks for reporting it.
May 13, 2010 01:18 PM|don.raman|LINK
php-cgi.exe doesn't handle this appropriately. So this feature will not work with php-cgi.exe. In order to have this feature work with php-cgi.exe a fix is required in PHP code.
So answer to your original question is, signal before terminate will not work with php-cgi.exe as a FastCGI process.